diff --git a/fpga/lib/pcie/.test_durations b/fpga/lib/pcie/.test_durations index 7c5263c04..13ad8a78b 100644 --- a/fpga/lib/pcie/.test_durations +++ b/fpga/lib/pcie/.test_durations @@ -1,246 +1,262 @@ { -"example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/test_fpga_core.py::test_fpga_core": 2.916534410789609, -"example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.792815685272217, -"example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.1711929999291897, -"example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.523538811132312, -"example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 2.9885319620370865, -"example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 2.9102583527565002, -"example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 2.9578798823058605, -"example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 2.9110837541520596, -"example/VCU118/fpga_axi_x8/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.1017360910773277, -"example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.3821051251143217, -"example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.31473832949996, -"example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 4.393863594159484, -"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[128-128]": 23.014210656285286, -"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[128-64]": 54.48078823275864, -"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[256-128]": 102.50034037604928, -"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[256-64]": 312.92554699257016, -"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[128-128]": 5.00186756812036, -"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[128-64]": 8.81907420605421, -"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[256-128]": 18.002375923097134, -"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[256-64]": 52.303941706195474, -"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[128]": 83.91109788417816, -"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[256]": 124.33533678203821, -"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[512]": 232.16960954107344, -"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[64]": 84.28613908961415, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-0]": 105.70164067298174, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-1]": 71.86684249900281, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-2]": 110.42481097020209, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-3]": 112.10443865321577, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4092]": 119.83291484601796, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4093]": 120.1497967261821, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4094]": 124.17319979518652, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4095]": 124.64987274818122, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-0]": 276.0493700131774, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-1]": 291.5865914337337, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-2]": 228.709343733266, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-3]": 212.29017327725887, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4092]": 360.3312690295279, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4093]": 347.08058276586235, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4094]": 363.85544519871473, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4095]": 341.85322116315365, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-0]": 872.8448779862374, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-1]": 288.02628028579056, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-2]": 893.6039412412792, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-3]": 890.3304248359054, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4092]": 1180.3968361616135, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4093]": 1207.7241523172706, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4094]": 1190.9575752746314, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4095]": 1203.2844780068845, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-0]": 64.5851038582623, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-1]": 58.3931063786149, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-2]": 61.39967245236039, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-3]": 64.06594183295965, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4092]": 69.31046131625772, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4093]": 55.06979448720813, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4094]": 57.849495800212026, -"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4095]": 56.50290404818952, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-0]": 129.90480903349817, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-1]": 119.45754928700626, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-2]": 141.85422517359257, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-3]": 97.6639727205038, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4092]": 145.23641748726368, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4093]": 141.06131340749562, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4094]": 120.68941901810467, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4095]": 146.7782313656062, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-0]": 300.2570718713105, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-1]": 402.23831034451723, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-2]": 412.6096981149167, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-3]": 334.7497763298452, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4092]": 418.09789489768445, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4093]": 357.2038128450513, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4094]": 353.948193218559, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4095]": 415.08037544228137, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-0]": 1332.2133955806494, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-1]": 1321.1691774204373, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-2]": 970.2082796096802, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-3]": 1345.165429232642, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4092]": 1568.7676404062659, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4093]": 1549.2790504395962, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4094]": 1554.162967255339, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4095]": 1568.6706973798573, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-0]": 60.46724066697061, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-1]": 65.01189825311303, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-2]": 63.4063877761364, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-3]": 72.554034197703, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4092]": 76.26433479227126, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4093]": 68.51169106550515, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4094]": 63.710983503609896, -"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4095]": 41.91661210358143, -"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[128]": 58.874975653365254, -"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[256]": 71.85352810658514, -"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[512]": 67.03068605065346, -"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[64]": 70.01639139279723, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-0]": 82.01821563020349, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-1]": 84.34989723004401, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-2]": 88.53845448791981, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-3]": 82.76248260773718, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4092]": 89.002327689901, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4093]": 91.94100417383015, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4094]": 91.77720731496811, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4095]": 85.29362261667848, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-0]": 164.12575116194785, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-1]": 162.31486722826958, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-2]": 132.3263214211911, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-3]": 166.349397206679, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4092]": 206.64574633538723, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4093]": 202.2808986864984, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4094]": 230.88222755677998, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4095]": 181.47310289740562, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-0]": 447.1190050560981, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-1]": 510.36900823004544, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-2]": 475.9582682065666, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-3]": 369.02229719236493, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4092]": 632.010077547282, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4093]": 623.3498513679951, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4094]": 634.9828971829265, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4095]": 678.3867132682353, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-0]": 56.452902264893055, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-1]": 49.822157483547926, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-2]": 50.2586698718369, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-3]": 55.92606351338327, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4092]": 54.35491492040455, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4093]": 53.91469735838473, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4094]": 61.54035664536059, -"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4095]": 36.88868669420481, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-0]": 81.31267609633505, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-1]": 74.84810334816575, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-2]": 91.1239520162344, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-3]": 85.00789263099432, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4092]": 70.5354738086462, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4093]": 95.84557400457561, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4094]": 61.39850436709821, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4095]": 92.04206262715161, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-0]": 181.5985076352954, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-1]": 214.64819343201816, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-2]": 225.5085930712521, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-3]": 215.27064360119402, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4092]": 239.7835914567113, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4093]": 249.05179824121296, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4094]": 224.648066656664, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4095]": 244.2789028082043, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-0]": 673.1442274712026, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-1]": 671.5785223823041, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-2]": 661.0973074473441, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-3]": 467.93026498891413, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4092]": 641.0226412769407, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4093]": 664.8428070358932, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4094]": 769.693888740614, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4095]": 537.4758495204151, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-0]": 44.224665900692344, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-1]": 39.25952201709151, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-2]": 47.09516667947173, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-3]": 51.95439605973661, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4092]": 50.5628147572279, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4093]": 50.84800132364035, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4094]": 53.38332620635629, -"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4095]": 48.12064493447542, -"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[128]": 109.95931106247008, -"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[256]": 225.29804465174675, -"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[512]": 1483.8865280915052, -"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[64]": 43.57202509045601, -"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[128]": 68.31862393021584, -"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[256]": 241.10722985491157, -"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[512]": 835.688470305875, -"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[64]": 29.414648678153753, -"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[128]": 111.57632253877819, -"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[256]": 235.19530341401696, -"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[512]": 2008.862396882847, -"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[64]": 42.99466290138662, -"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[128]": 23.64178654924035, -"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[256]": 18.50641735084355, -"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[512]": 19.792408687993884, -"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[64]": 11.810216020792723, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-1]": 45.46886810101569, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-3]": 44.63418922200799, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4093]": 49.56677965633571, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-2]": 80.09546222910285, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4094]": 49.05143196322024, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-3]": 72.64273344352841, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-0]": 42.531037176027894, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-2]": 45.73727682605386, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4092]": 46.10116964764893, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4093]": 98.02695255354047, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4092]": 96.26230247877538, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4095]": 46.497494142502546, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-1]": 80.86216964386404, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4094]": 101.8242319021374, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-0]": 59.50855052471161, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4095]": 94.16053957305849, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-0]": 133.46184592694044, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4093]": 271.6977021470666, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-1]": 177.764847766608, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-2]": 223.65542648546398, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4092]": 272.9659264907241, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-1]": 698.6140406429768, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-2]": 700.7923820130527, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-3]": 227.8394887316972, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4092]": 655.5252631176263, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4094]": 278.05639548040926, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4095]": 203.0007848329842, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4094]": 869.9473037496209, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4093]": 971.8388572502881, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-3]": 702.6180536206812, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-0]": 687.0177703388035, -"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4095]": 963.3620585650206, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4093]": 40.62531438656151, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4095]": 56.59193644300103, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4094]": 36.51889197528362, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-1]": 54.01949325762689, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-2]": 57.47751363739371, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-3]": 56.31052377447486, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-0]": 55.35047259554267, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4092]": 31.88961515389383, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-1]": 116.28371364250779, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4094]": 1348.4973489232361, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4092]": 1344.273872120306, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-0]": 118.59797800518572, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4094]": 395.011361759156, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-2]": 120.40170429833233, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-3]": 122.76581878401339, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4095]": 1346.0987539943308, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-0]": 1164.3820233866572, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4093]": 927.8997925147414, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-1]": 1164.2590152490884, -"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[128-32]": 6.970676742494106, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4095]": 389.3293671924621, -"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[512-32]": 7.297583125531673, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4092]": 130.12535612098873, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4093]": 136.43636007234454, -"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[256-32]": 8.52725044824183, -"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[64-32]": 7.2995394710451365, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-1]": 353.14526508376, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-3]": 1156.7327877692878, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4094]": 90.23185868375003, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4095]": 84.63998504914343, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-0]": 345.7283751256764, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-2]": 1140.431740367785, -"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[64]": 514.5902478210628, -"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[512]": 272.1462731231004, -"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[256]": 214.09162938408554, -"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[128]": 356.17742117121816, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-2]": 292.8214397095144, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4093]": 353.54873054102063, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-3]": 318.3103033080697, -"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4092]": 355.5807752367109 +"example/ADM_PCIE_9V3/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.802748524583876, +"example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.3258837070316076, +"example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.5839403150603175, +"example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.299394723959267, +"example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 4.124049663543701, +"example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.3842510767281055, +"example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.191984139382839, +"example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 4.09519069083035, +"example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.4458096409216523, +"example/VCU118/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.4719844488427043, +"example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.6846165349707007, +"example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py::test_fpga_core": 3.3272919971495867, +"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[128-128]": 19.773019718006253, +"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[128-64]": 51.87864843290299, +"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[256-128]": 101.22536892443895, +"tb/dma_client_axis_sink/test_dma_client_axis_sink.py::test_dma_client_axis_sink[256-64]": 308.145457116887, +"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[128-128]": 4.561003003269434, +"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[128-64]": 9.706514734774828, +"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[256-128]": 20.12889632023871, +"tb/dma_client_axis_source/test_dma_client_axis_source.py::test_dma_client_axis_source[256-64]": 52.55990722961724, +"tb/dma_if_axi/test_dma_if_axi.py::test_dma_if_axi[128]": 343.75319696124643, +"tb/dma_if_axi/test_dma_if_axi.py::test_dma_if_axi[64]": 192.47738879267126, +"tb/dma_if_axi_rd/test_dma_if_axi_rd.py::test_dma_if_axi_rd[128]": 3491.0948395263404, +"tb/dma_if_axi_rd/test_dma_if_axi_rd.py::test_dma_if_axi_rd[64]": 1059.559308808297, +"tb/dma_if_axi_wr/test_dma_if_axi_wr.py::test_dma_if_axi_wr[128]": 3858.4138430636376, +"tb/dma_if_axi_wr/test_dma_if_axi_wr.py::test_dma_if_axi_wr[64]": 1131.2940800320357, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-0]": 79.01666341349483, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-1]": 81.8225589543581, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-2]": 86.10154215991497, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-3]": 91.41646837163717, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4092]": 98.94065702427179, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4093]": 101.9449352947995, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4094]": 102.73214660491794, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[128-4095]": 104.02288454957306, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-0]": 225.88785719592124, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-1]": 235.59673424530774, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-2]": 213.09597409889102, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-3]": 218.18825437873602, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4092]": 276.1784340329468, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4093]": 296.4947264175862, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4094]": 279.2957340814173, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[256-4095]": 287.87789774592966, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-0]": 717.0733665134758, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-1]": 724.7934947470203, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-2]": 728.9005477866158, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-3]": 724.4264851529151, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4092]": 945.6526354402304, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4093]": 966.9157891590148, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4094]": 972.3732780404389, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[512-4095]": 984.5325328214094, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-0]": 42.60674643050879, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-1]": 50.021843056194484, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-2]": 44.81453281734139, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-3]": 45.96749486401677, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4092]": 48.09584825672209, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4093]": 54.773935317993164, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4094]": 49.8832717705518, +"tb/dma_if_pcie_rd/test_dma_if_pcie_rd.py::test_dma_if_pcie_rd[64-4095]": 49.52170397993177, +"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[128]": 91.79372521769255, +"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[256]": 137.57448218669742, +"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[512]": 228.36221320554614, +"tb/dma_if_pcie_us/test_dma_if_pcie_us.py::test_dma_if_pcie_us[64]": 88.39011643826962, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-0]": 111.84856793377548, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-1]": 107.44950049649924, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-2]": 108.67767435219139, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-3]": 112.894415743649, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4092]": 121.19480721652508, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4093]": 124.84660611208528, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4094]": 125.49157247878611, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[128-4095]": 130.4821817614138, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-0]": 281.71041271369904, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-1]": 297.7064002659172, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-2]": 305.9379079742357, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-3]": 306.9792539207265, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4092]": 349.9477741466835, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4093]": 362.3564678877592, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4094]": 351.5242036776617, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[256-4095]": 354.60532931704074, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-0]": 920.4725245833397, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-1]": 895.2650481760502, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-2]": 929.2675906699151, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-3]": 911.4231735393405, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4092]": 1199.7578652864322, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4093]": 1209.5915048634633, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4094]": 1196.6806777771562, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[512-4095]": 1206.1904021305963, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-0]": 63.814447931945324, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-1]": 72.06102177780122, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-2]": 68.85669411346316, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-3]": 63.027560509741306, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4092]": 77.0296537950635, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4093]": 75.10126299411058, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4094]": 78.24143446795642, +"tb/dma_if_pcie_us_rd/test_dma_if_pcie_us_rd.py::test_dma_if_pcie_us_rd[64-4095]": 68.77312798704952, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-0]": 133.72164732776582, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-1]": 131.1819771323353, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-2]": 133.6107413265854, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-3]": 145.00093348510563, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4092]": 151.41237839963287, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4093]": 151.64348626695573, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4094]": 145.58419975917786, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[128-4095]": 151.75187445711344, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-0]": 399.94164040964097, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-1]": 424.67655873671174, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-2]": 408.84541436843574, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-3]": 411.0121839726344, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4092]": 419.588231138885, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4093]": 420.1934391334653, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4094]": 432.63656940776855, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[256-4095]": 444.8876341599971, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-0]": 1362.0081015806645, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-1]": 1344.387565410696, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-2]": 1347.0662414124236, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-3]": 1373.6735086627305, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4092]": 1613.4211130375043, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4093]": 1601.7280606981367, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4094]": 1594.237581346184, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[512-4095]": 1588.2506092460826, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-0]": 61.83722551912069, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-1]": 65.39742449577898, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-2]": 64.76823486480862, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-3]": 72.31702047307044, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4092]": 67.24590519536287, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4093]": 69.52025263477117, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4094]": 73.8641168512404, +"tb/dma_if_pcie_us_wr/test_dma_if_pcie_us_wr.py::test_dma_if_pcie_us_wr[64-4095]": 70.58423026651144, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-0]": 124.62044448871166, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-1]": 125.3179573174566, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-2]": 123.52719444595277, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-3]": 121.50697969086468, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4092]": 135.5547366840765, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4093]": 141.64910212531686, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4094]": 135.56749817170203, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[128-4095]": 134.49233472626656, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-0]": 359.4473678143695, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-1]": 358.3363642189652, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-2]": 326.40840378869325, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-3]": 330.50785585306585, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4092]": 365.45916066505015, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4093]": 397.1625804528594, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4094]": 423.07104915659875, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[256-4095]": 418.8784888172522, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-0]": 1156.8311005486175, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-1]": 1239.349814729765, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-2]": 1215.0386044280604, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-3]": 1225.8721883352846, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4092]": 1404.0681659830734, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4093]": 1380.8230891777202, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4094]": 1410.8937428295612, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[512-4095]": 1405.3264035871252, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-0]": 56.316388356499374, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-1]": 57.6794781209901, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-2]": 55.86831241194159, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-3]": 56.86479601264, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4092]": 58.64155148807913, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4093]": 61.130343430675566, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4094]": 63.11295567639172, +"tb/dma_if_pcie_wr/test_dma_if_pcie_wr.py::test_dma_if_pcie_wr[64-4095]": 68.31885484047234, +"tb/pcie_axi_master/test_pcie_axi_master.py::test_pcie_axi_master[128]": 200.1484386594966, +"tb/pcie_axi_master/test_pcie_axi_master.py::test_pcie_axi_master[64]": 70.23948794603348, +"tb/pcie_axi_master_rd/test_pcie_axi_master_rd.py::test_pcie_axi_master_rd[128]": 55.44184198230505, +"tb/pcie_axi_master_rd/test_pcie_axi_master_rd.py::test_pcie_axi_master_rd[64]": 21.735506244935095, +"tb/pcie_axi_master_wr/test_pcie_axi_master_wr.py::test_pcie_axi_master_wr[128]": 120.52425152715296, +"tb/pcie_axi_master_wr/test_pcie_axi_master_wr.py::test_pcie_axi_master_wr[64]": 37.43932660203427, +"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[128-32]": 107.02804043050855, +"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[256-32]": 231.14591807499528, +"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[512-32]": 535.6075880806893, +"tb/pcie_axil_master/test_pcie_axil_master.py::test_pcie_axil_master[64-32]": 79.63517816364765, +"tb/pcie_axil_master_minimal/test_pcie_axil_master_minimal.py::test_pcie_axil_master_minimal[128-32]": 8.106846507638693, +"tb/pcie_axil_master_minimal/test_pcie_axil_master_minimal.py::test_pcie_axil_master_minimal[256-32]": 7.857231725007296, +"tb/pcie_axil_master_minimal/test_pcie_axil_master_minimal.py::test_pcie_axil_master_minimal[512-32]": 6.845761440694332, +"tb/pcie_axil_master_minimal/test_pcie_axil_master_minimal.py::test_pcie_axil_master_minimal[64-32]": 9.676500081084669, +"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[128]": 60.31055367924273, +"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[256]": 75.90688497480005, +"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[512]": 120.13413332402706, +"tb/pcie_us_axi_dma/test_pcie_us_axi_dma.py::test_pcie_us_axi_dma[64]": 71.76475979294628, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-0]": 87.44113349728286, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-1]": 88.47830758430064, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-2]": 82.34276087768376, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-3]": 77.59432693012059, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4092]": 85.14064910728484, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4093]": 91.7452895604074, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4094]": 94.4083996778354, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[128-4095]": 92.3458092212677, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-0]": 176.11909464839846, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-1]": 181.43843808211386, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-2]": 180.06111937575042, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-3]": 189.92403083574027, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4092]": 201.8262586351484, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4093]": 217.1350730843842, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4094]": 213.67476241104305, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[256-4095]": 223.82260006666183, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-0]": 513.6400478417054, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-1]": 518.773749073036, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-2]": 527.7008009385318, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-3]": 514.4352704267949, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4092]": 622.5443422403187, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4093]": 651.5169745255262, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4094]": 652.1921855630353, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[512-4095]": 659.5976075418293, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-0]": 52.65964440535754, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-1]": 52.878225741907954, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-2]": 53.243976899422705, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-3]": 52.389048451557755, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4092]": 59.462078055366874, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4093]": 56.5677183335647, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4094]": 57.26419168245047, +"tb/pcie_us_axi_dma_rd/test_pcie_us_axi_dma_rd.py::test_pcie_us_axi_dma_rd[64-4095]": 63.658326268196106, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-0]": 81.2870606156066, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-1]": 85.24885594844818, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-2]": 89.51225053425878, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-3]": 88.2058340003714, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4092]": 102.40149004478008, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4093]": 97.50177231896669, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4094]": 96.14614683017135, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[128-4095]": 115.3958765314892, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-0]": 206.25918624270707, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-1]": 218.5192295294255, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-2]": 210.33749064989388, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-3]": 209.48760077543557, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4092]": 231.20978947915137, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4093]": 236.96860673092306, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4094]": 255.79039429314435, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[256-4095]": 255.53616074565798, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-0]": 689.6088027246296, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-1]": 657.8039822680876, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-2]": 661.6122091403231, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-3]": 687.648093345575, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4092]": 777.6627761116251, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4093]": 773.0814327206463, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4094]": 771.2406269712374, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[512-4095]": 780.6499522561207, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-0]": 45.34078027307987, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-1]": 50.8450885117054, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-2]": 52.388750846497715, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-3]": 51.61842204630375, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4092]": 51.89234064798802, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4093]": 51.93105165846646, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4094]": 52.75161452963948, +"tb/pcie_us_axi_dma_wr/test_pcie_us_axi_dma_wr.py::test_pcie_us_axi_dma_wr[64-4095]": 61.68179198168218, +"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[128]": 110.96181839238852, +"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[256]": 406.9330044342205, +"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[512]": 1723.517820496112, +"tb/pcie_us_axi_master/test_pcie_us_axi_master.py::test_pcie_us_axi_master[64]": 45.3040759973228, +"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[128]": 71.62603108398616, +"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[256]": 223.89475911017507, +"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[512]": 831.0976231973618, +"tb/pcie_us_axi_master_rd/test_pcie_us_axi_master_rd.py::test_pcie_us_axi_master_rd[64]": 30.80006799288094, +"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[128]": 117.03282310813665, +"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[256]": 429.93650751560926, +"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[512]": 2069.762047354132, +"tb/pcie_us_axi_master_wr/test_pcie_us_axi_master_wr.py::test_pcie_us_axi_master_wr[64]": 38.9829649431631, +"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[128]": 20.891817398369312, +"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[256]": 19.21851094532758, +"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[512]": 19.582210627384484, +"tb/pcie_us_axil_master/test_pcie_us_axil_master.py::test_pcie_us_axil_master[64]": 24.837274935096502, +"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[128]": 397.81249309983104, +"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[256]": 349.69978694897145, +"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[512]": 319.8452987289056, +"tb/pcie_us_if/test_pcie_us_if.py::test_pcie_us_if[64]": 578.6278276052326 } \ No newline at end of file diff --git a/fpga/lib/pcie/README.md b/fpga/lib/pcie/README.md index 4f794e4ec..817098acb 100644 --- a/fpga/lib/pcie/README.md +++ b/fpga/lib/pcie/README.md @@ -8,87 +8,60 @@ GitHub repository: https://github.com/alexforencich/verilog-pcie ## Introduction -Collection of PCI express related components. Includes PCIe to AXI and AXI -lite bridges, a simple PCIe AXI DMA engine, and a flexible, high-performance -DMA subsystem. Currently supports operation with the Xilinx UltraScale and -UltraScale+ PCIe hard IP cores with interfaces between 64 and 512 bits. -Includes full cocotb testbenches that utilize -[cocotbext-pcie](https://github.com/alexforencich/cocotbext-pcie) and -[cocotbext-axi](https://github.com/alexforencich/cocotbext-axi). +Collection of PCI express related components. Includes PCIe to AXI and AXI lite bridges and a flexible, high-performance DMA subsystem. Currently supports operation with several FPGA families from Xilinx and Intel. Includes full cocotb testbenches that utilize [cocotbext-pcie](https://github.com/alexforencich/cocotbext-pcie) and [cocotbext-axi](https://github.com/alexforencich/cocotbext-axi). + +Example designs are included for the following FPGA boards: + +* BittWare 520N-MX (Intel Stratix 10 MX 1SM21CHU2F53E2VG) +* Exablaze ExaNIC X10 (Xilinx Kintex UltraScale XCKU035) +* Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P) +* Intel Stratix 10 MX dev kit (Intel Stratix 10 MX 1SM21CHU1F53E1VG) ## Documentation +### FPGA-independent PCIe + +The PCIe modules use a generic, FPGA-independent interface for handling PCIe TLPs. This permits the same core logic to be used on multiple FPGA families, with interface shims to connect to the PCIe IP on each target device. + +The `pcie_us_if` module is an adaptation shim for Xilinx 7-series, UltraScale, and UltraScale+. It handles the main datapath, configuration space parameters, MSI interrupts, and flow control. + +The `pcie_s10_if` module is an adaptation shim for Intel Stratix 10 GX/SX/TX/MX series FPGAs that use the H-Tile or L-Tile for PCIe. It handles the main datapath, configuration space parameters, MSI interrupts, and flow control. + ### PCIe AXI and AXI lite master -The `pcie_us_axi_master` and `pcie_us_axil_master` modules provide a bridge -between PCIe and AXI. These can be used to implement PCIe BARs. The -pcie_us_axil_master module is a very simple module for providing register -access, supporting only 32 bit operations. The `pcie_us_axi_master` module is -more complex, converting PCIe operations to AXI bursts. It can be used to -terminate device-to-device DMA operations with reasonable performance. The -`pcie_us_axis_cq_demux` module can be used to demultiplex PCIe operations based -on the target BAR. +The `pcie_axi_master`, `pcie_axil_master`, and `pcie_axil_master_minimal` modules provide a bridge between PCIe and AXI. These can be used to implement PCIe BARs. -### PCIe AXI DMA +The `pcie_axil_master_minimal` module is a very simple module for providing register access, supporting only 32 bit operations. -The `pcie_us_axi_dma` module provides a DMA engine with an internal AXI -interface. The AXI interface width must match the PCIe interface width. The -module directly translates AXI operations into PCIe operations. As a result, -it is relatively simple, but the performance is limited due to the constraints -of the AXI interface. Backpressure on the AXI interface is also passed -through to the PCIe interface. +The `pcie_axi_master` module is more complex, converting PCIe operations to AXI bursts. It can be used to terminate device-to-device DMA operations with reasonable performance. -The `pcie_axi_dma_desc_mux` module can be used to share the AXI DMA module -between multiple request sources. +The `pcie_tlp_demux_bar` module can be used to demultiplex PCIe operations based on the target BAR. ### Flexible DMA subsystem -The split DMA interface/DMA client modules support highly flexible, highly -performant DMA operations. The DMA interface and DMA client modules are -connected by dual port RAMs with a high performance segmented memory -interface. The segmented memory interface is a better 'impedance match' to -the PCIe hard core interface - data realignment can be done in the same clock -cycle; no bursts, address decoding, arbitration, or reordering simplifies -implementation and provides much higher performance than AXI. The architecture -is also quite flexible as it decouples the DMA interface from the clients with -dual port RAMs, enabling mixing different client interface types and widths -and even supporting clients running in different clock domains without -datapath FIFOs. +The split DMA interface/DMA client modules support highly flexible, highly performant DMA operations. The DMA interface and DMA client modules are connected by dual port RAMs with a high performance segmented memory interface. The segmented memory interface is a better 'impedance match' to the PCIe hard core interface - data realignment can be done in the same clock cycle; no bursts, address decoding, arbitration, or reordering simplifies implementation and provides much higher performance than AXI. The architecture is also quite flexible as it decouples the DMA interface from the clients with dual port RAMs, enabling mixing different client interface types and widths and even supporting clients running in different clock domains without datapath FIFOs. ![DMA system block diagram](dma_block.svg) -The `dma_if_pcie_us` module connects the Xilinx UltraScale PCIe interface to -the segmented memory interface. Currently, it does not support TLP straddling, -but it should be possible to support this with the segmented interface. +The `dma_if_pcie` module connects a generic, FPGA-independent PCIe interface to the segmented memory interface. -The `dma_psdpram` module is a dual clock, parallel simple dual port RAM module -with a segmented interface. The depth is independently adjustable from the -address width, simplifying use of the segmented interface. The module also contains a parametrizable output pipeline register to improve timing. +The `dma_if_axi` module connects an AXI interface to the segmented memory interface. -The `dma_if_mux` module enables sharing the DMA interface across several DMA -clients. This module handles the tags and select lines appropriately on both -the descriptor and segmented memory interface for plug-and-play operation -without address assignment - routing is completely determined by component -connections. The module also contains a FIFO to maintain read data ordering -across multiple clients. Make sure to equalize pipeline delay across all -paths for maximum performance. +The `dma_psdpram` module is a dual clock, parallel simple dual port RAM module with a segmented interface. The depth is independently adjustable from the address width, simplifying use of the segmented interface. The module also contains a parametrizable output pipeline register to improve timing. -DMA client modules connect the segmented memory interface to different -internal interfaces. +The `dma_if_mux` module enables sharing the DMA interface across several DMA clients. This module handles the tags and select lines appropriately on both the descriptor and segmented memory interface for plug-and-play operation without address assignment - routing is completely determined by component connections. The module also contains a FIFO to maintain read data ordering across multiple clients. Make sure to equalize pipeline delay across all paths for maximum performance. -The `dma_client_axis_source` and `dma_client_axis_sink` modules provide support -for streaming DMA over AXI stream. The AXI stream width can be any power of -two fraction of the segmented memory interface width. +DMA client modules connect the segmented memory interface to different internal interfaces. + +The `dma_client_axis_source` and `dma_client_axis_sink` modules provide support for streaming DMA over AXI stream. The AXI stream width can be any power of two fraction of the segmented memory interface width. ### `arbiter` module -General-purpose parametrizable arbiter. Supports priority and round-robin -arbitration. Supports blocking until request release or acknowledge. +General-purpose parametrizable arbiter. Supports priority and round-robin arbitration. Supports blocking until request release or acknowledge. ### `axis_arb_mux` module -Frame-aware AXI stream arbitrated multiplexer with parametrizable data width -and port count. Supports priority and round-robin arbitration. +Frame-aware AXI stream arbitrated multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. ### `dma_client_axis_sink` module @@ -98,75 +71,69 @@ AXI stream sink DMA client module. Uses a segmented memory interface. AXI stream source DMA client module. Uses a segmented memory interface. +### `dma_if_axi` module + +AXI DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. + +### `dma_if_axi_rd` module + +AXI DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. + +### `dma_if_axi_wr` module + +AXI DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. + ### `dma_if_desc_mux` module -DMA interface descriptor mux module. Enables sharing a DMA interface module -between multiple DMA client modules. +DMA interface descriptor mux module. Enables sharing a DMA interface module between multiple DMA client modules. ### `dma_if_mux` module -DMA interface mux module. Enables sharing a DMA interface module between -multiple DMA client modules. Wrapper for `dma_if_mux_rd` and `dma_if_mux_wr`. +DMA interface mux module. Enables sharing a DMA interface module between multiple DMA client modules. Wrapper for `dma_if_mux_rd` and `dma_if_mux_wr`. ### `dma_if_mux_rd` module -DMA interface mux module. Enables sharing a DMA interface module between -multiple DMA client modules. Wrapper for `dma_if_desc_mux` and -`dma_ram_demux_wr`. +DMA interface mux module. Enables sharing a DMA interface module between multiple DMA client modules. Wrapper for `dma_if_desc_mux` and `dma_ram_demux_wr`. ### `dma_if_mux_wr` module -DMA interface mux module. Enables sharing a DMA interface module between -multiple DMA client modules. Wrapper for `dma_if_desc_mux` and -`dma_ram_demux_rd`. +DMA interface mux module. Enables sharing a DMA interface module between multiple DMA client modules. Wrapper for `dma_if_desc_mux` and `dma_ram_demux_rd`. ### `dma_if_pcie` module -PCIe DMA interface module. Parametrizable interface width. Uses a double -width segmented memory interface. +PCIe DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. ### `dma_if_pcie_rd` module -PCIe DMA interface module. Parametrizable interface width. Uses a double -width segmented memory interface. +PCIe DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. ### `dma_if_pcie_wr` module -PCIe DMA interface module. Parametrizable interface width. Uses a double -width segmented memory interface. +PCIe DMA interface module. Parametrizable interface width. Uses a double width segmented memory interface. ### `dma_if_pcie_us` module -PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, -128, 256, and 512 bit datapaths. Uses a double width segmented memory -interface. Wrapper for `dma_if_pcie_us_rd` and `dma_if_pcie_us_wr`. +PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface. Wrapper for `dma_if_pcie_us_rd` and `dma_if_pcie_us_wr`. ### `dma_if_pcie_us_rd` module -PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, -128, 256, and 512 bit datapaths. Uses a double width segmented memory -interface. +PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface. ### `dma_if_pcie_us_wr` module -PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, -128, 256, and 512 bit datapaths. Uses a double width segmented memory -interface. +PCIe DMA interface module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Uses a double width segmented memory interface. ### `dma_psdpram` module -DMA RAM module. Segmented simple dual port RAM to connect a DMA interface -module to a DMA client. +DMA RAM module. Segmented simple dual port RAM to connect a DMA interface module to a DMA client. ### `dma_psdpram_async` module -DMA RAM module with asynchronous clocks. Segmented simple dual port RAM to -connect a DMA interface module to a DMA client. +DMA RAM module with asynchronous clocks. Segmented simple dual port RAM to connect a DMA interface module to a DMA client. ### `dma_ram_demux` module -DMA RAM interface demultiplexer module. Wrapper for `dma_ram_demux_rd` and -`dma_ram_demux_wr`. +DMA RAM interface demultiplexer module. Wrapper for `dma_ram_demux_rd` and `dma_ram_demux_wr`. ### `dma_ram_demux_rd` module @@ -178,14 +145,11 @@ DMA RAM interface demultiplexer module for write operations. ### `pcie_axi_dma_desc_mux` module -Descriptor multiplexer/demultiplexer for PCIe AXI DMA module. Enables sharing -the PCIe AXI DMA module between multiple request sources, interleaving -requests and distributing responses. +Descriptor multiplexer/demultiplexer for PCIe AXI DMA module. Enables sharing the PCIe AXI DMA module between multiple request sources, interleaving requests and distributing responses. ### `pcie_axi_master` module -PCIe AXI master module. Parametrizable interface width and AXI burst length. -Wrapper for `pcie_axi_master_rd` and `pcie_axi_master_wr`. +PCIe AXI master module. Parametrizable interface width and AXI burst length. Wrapper for `pcie_axi_master_rd` and `pcie_axi_master_wr`. ### `pcie_axi_master_rd` module @@ -201,9 +165,27 @@ PCIe AXI lite master module. Parametrizable interface width. ### `pcie_axil_master_minimal` module -Minimal PCIe AXI lite master module. Parametrizable interface width. Only -supports aligned 32-bit operations, all other operations will result in a -completer abort. Only supports 32-bit AXI lite. +Minimal PCIe AXI lite master module. Parametrizable interface width. Only supports aligned 32-bit operations, all other operations will result in a completer abort. Only supports 32-bit AXI lite. + +### `pcie_s10_cfg` module + +Configuration shim for Intel Stratix 10 GX/SX/TX/MX series FPGAs (H-Tile/L-Tile). + +### `pcie_s10_if` module + +PCIe interface shim for Intel Stratix 10 GX/SX/TX/MX series FPGAs (H-Tile/L-Tile). Wrapper for all Intel Stratix 10 GX/SX/TX/MX PCIe interface shims. + +### `pcie_s10_if_rx` module + +PCIe interface shim (RX) for Intel Stratix 10 GX/SX/TX/MX series FPGAs (H-Tile/L-Tile). + +### `pcie_s10_if_tx` module + +PCIe interface shim (TX) for Intel Stratix 10 GX/SX/TX/MX series FPGAs (H-Tile/L-Tile). + +### `pcie_s10_msi` module + +MSI shim for Intel Stratix 10 GX/SX/TX/MX series FPGAs (H-Tile/L-Tile). ### `pcie_tlp_demux` module @@ -211,8 +193,7 @@ PCIe TLP demultiplexer module. ### `pcie_tlp_demux_bar` module -PCIe TLP demultiplexer module. Wrapper for `pcie_tlp_demux` with -parametrizable BAR ID matching logic. +PCIe TLP demultiplexer module. Wrapper for `pcie_tlp_demux` with parametrizable BAR ID matching logic. ### `pcie_tlp_mux` module @@ -220,52 +201,39 @@ PCIe TLP multiplexer module. ### `pcie_us_axi_dma` module -PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, -and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for -`pcie_us_axi_dma_rd` and `pcie_us_axi_dma_wr`. +PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for `pcie_us_axi_dma_rd` and `pcie_us_axi_dma_wr`. ### `pcie_us_axi_dma_rd` module -PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, -and 512 bit datapaths. Parametrizable AXI burst length. +PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. ### `pcie_us_axi_dma_wr` module -PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, -and 512 bit datapaths. Parametrizable AXI burst length. +PCIe AXI DMA module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. ### `pcie_us_axi_master` module -PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, -256, and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for -`pcie_us_axi_master_rd` and `pcie_us_axi_master_wr`. +PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. Wrapper for `pcie_us_axi_master_rd` and `pcie_us_axi_master_wr`. ### `pcie_us_axi_master_rd` module -PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, -256, and 512 bit datapaths. Parametrizable AXI burst length. +PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. ### `pcie_us_axi_master_wr` module -PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, -256, and 512 bit datapaths. Parametrizable AXI burst length. +PCIe AXI master module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit datapaths. Parametrizable AXI burst length. ### `pcie_us_axil_master` module -PCIe AXI lite master module for Xilinx UltraScale series FPGAs. Supports 64, -128, 256, and 512 bit PCIe interfaces. +PCIe AXI lite master module for Xilinx UltraScale series FPGAs. Supports 64, 128, 256, and 512 bit PCIe interfaces. ### `pcie_us_axis_cq_demux` module -Demux module for Xilinx UltraScale CQ interface. Can be used to route -incoming requests based on function, BAR, and other fields. Supports 64, 128, -256, and 512 bit datapaths. +Demux module for Xilinx UltraScale CQ interface. Can be used to route incoming requests based on function, BAR, and other fields. Supports 64, 128, 256, and 512 bit datapaths. ### `pcie_us_axis_rc_demux` module -Demux module for Xilinx UltraScale RC interface. Can be used to route -incoming completions based on the requester ID (function). Supports 64, 128, -256, and 512 bit datapaths. +Demux module for Xilinx UltraScale RC interface. Can be used to route incoming completions based on the requester ID (function). Supports 64, 128, 256, and 512 bit datapaths. ### `pcie_us_cfg` module @@ -273,8 +241,7 @@ Configuration shim for Xilinx UltraScale series FPGAs. ### `pcie_us_if` module -PCIe interface shim for Xilinx UltraScale series FPGAs. Wrapper for all -Xilinx UltraScale PCIe interface shims. +PCIe interface shim for Xilinx UltraScale series FPGAs. Wrapper for all Xilinx UltraScale PCIe interface shims. ### `pcie_us_if_cc` module @@ -302,8 +269,7 @@ Parametrizable priority encoder. ### `pulse_merge` module -Parametrizable pulse merge module. Combines several single-cycle pulse status -signals together. +Parametrizable pulse merge module. Combines several single-cycle pulse status signals together. ### Common signals @@ -315,16 +281,19 @@ signals together. axis_arb_mux.v : Parametrizable AXI stream mux dma_client_axis_sink.v : AXI stream sink DMA client dma_client_axis_source.v : AXI stream source DMA client + dma_if_axi.v : AXI DMA interface + dma_if_axi_rd.v : AXI DMA interface (read) + dma_if_axi_wr.v : AXI DMA interface (write) dma_if_desc_mux.v : DMA interface descriptor mux dma_if_mux.v : DMA interface mux dma_if_mux_rd.v : DMA interface mux (read) dma_if_mux_wr.v : DMA interface mux (write) - dma_if_pcie.v : DMA interface - dma_if_pcie_rd.v : DMA interface (read) - dma_if_pcie_wr.v : DMA interface (write) - dma_if_pcie_us.v : DMA interface for Xilinx UltraScale PCIe - dma_if_pcie_us_rd.v : DMA interface for Xilinx UltraScale PCIe (read) - dma_if_pcie_us_wr.v : DMA interface for Xilinx UltraScale PCIe (write) + dma_if_pcie.v : PCIe DMA interface + dma_if_pcie_rd.v : PCIe DMA interface (read) + dma_if_pcie_wr.v : PCIe DMA interface (write) + dma_if_pcie_us.v : PCIe DMA interface for Xilinx UltraScale + dma_if_pcie_us_rd.v : PCIe DMA interface for Xilinx UltraScale (read) + dma_if_pcie_us_wr.v : PCIe DMA interface for Xilinx UltraScale (write) dma_psdpram.v : DMA RAM (segmented simple dual port RAM) dma_psdpram_async.v : DMA RAM (segmented simple dual port RAM) dma_ram_demux.v : DMA RAM demultiplexer @@ -336,6 +305,11 @@ signals together. pcie_axi_master_wr.v : PCIe AXI master write module pcie_axil_master.v : PCIe AXI Lite master module pcie_axil_master_minimal.v : PCIe AXI Lite master module (minimal) + pcie_s10_cfg.v : Configuration shim for Intel Stratix 10 + pcie_s10_if.v : PCIe interface shim (Intel Stratix 10) + pcie_s10_if_rx.v : PCIe interface shim (RX) (Intel Stratix 10) + pcie_s10_if_tx.v : PCIe interface shim (TX) (Intel Stratix 10) + pcie_s10_msi.v : MSI shim for Intel Stratix 10 devices pcie_tlp_demux.v : PCIe TLP demultiplexer pcie_tlp_demux_bar.v : PCIe TLP demultiplexer (BAR ID) pcie_tlp_mux.v : PCIe TLP multiplexer diff --git a/fpga/lib/pcie/example/520N_MX/fpga/README.md b/fpga/lib/pcie/example/520N_MX/fpga/README.md new file mode 100644 index 000000000..c3ad0054e --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/README.md @@ -0,0 +1,19 @@ +# Verilog PCIe BittWare 520N-MX Example Design + +## Introduction + +This example design targets the BittWare 520N-MX FPGA board. + +The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design. + +* FPGA: 1SM21CHU2F53E2VG + +## How to build + +Run `make` to build. Ensure that the Intel Quartus Pro components are in PATH. + +Run `make` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled. + +## How to test + +Run `make program` to program the 520N-MX board with Quartus Pro. Then load the driver with `insmod example.ko`. Check dmesg for the output. diff --git a/fpga/lib/pcie/example/520N_MX/fpga/common/quartus_pro.mk b/fpga/lib/pcie/example/520N_MX/fpga/common/quartus_pro.mk new file mode 100644 index 000000000..1fc1b6fe8 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/common/quartus_pro.mk @@ -0,0 +1,179 @@ +################################################################### +# +# Makefile for Intel Quartus Prime Pro +# +# Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. Stratix 10 DX) +# FPGA_DEVICE - FPGA device (e.g. 1SD280PT2F55E1VG) +# SYN_FILES - space-separated list of source files +# IP_FILES - space-separated list of IP files +# IP_TCL_FILES - space-separated list of TCL files for qsys-script +# QSF_FILES - space-separated list of settings files +# SDC_FILES - space-separated list of timing constraint files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = "Stratix 10 DX" +# FPGA_DEVICE = 1SD280PT2F55E1VG +# SYN_FILES = rtl/fpga.v +# QSF_FILES = fpga.qsf +# SDC_FILES = fpga.sdc +# include ../common/quartus_pro.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# output files to hang on to +.PRECIOUS: %.sof %.ipregen.rpt %.syn.rpt %.fit.rpt %.asm.rpt %.sta.rpt +.SECONDARY: + +# any project specific settings +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) + +IP_FILES_REL = $(patsubst %, ../%, $(IP_FILES)) +IP_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_FILES))) + +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) +IP_TCL_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_TCL_FILES))) +IP_TCL_FILES_IP_INT = $(patsubst %.tcl, ip/%.ip, $(notdir $(IP_TCL_FILES))) + +ifdef QSF_FILES + QSF_FILES_REL = $(patsubst %, ../%, $(QSF_FILES)) +else + QSF_FILES_REL = ../$(FPGA_TOP).qsf +endif + +SDC_FILES_REL = $(patsubst %, ../%, $(SDC_FILES)) + +ASSIGNMENT_FILES = $(FPGA_TOP).qpf $(FPGA_TOP).qsf + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and database +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).sof + +quartus: $(FPGA_TOP).qpf + quartus $(FPGA_TOP).qpf + +tmpclean: + -rm -rf defines.v + -rm -rf *.rpt *.summary *.done *.smsg *.chg smart.log *.htm *.eqn *.pin *.qsf *.qpf *.sld *.txt *.qws *.stp + -rm -rf ip db qdb incremental_db reconfig_mif tmp-clearbox synth_dumps .qsys_edit + +clean: tmpclean + -rm -rf *.sof *.pof *.jdi *.jic *.map + +distclean: clean + -rm -rf rev + +syn: smart.log output_files/$(PROJECT).syn.rpt +fit: smart.log output_files/$(PROJECT).fit.rpt +asm: smart.log output_files/$(PROJECT).asm.rpt +sta: smart.log output_files/$(PROJECT).sta.rpt +smart: smart.log + +################################################################### +# Executable Configuration +################################################################### + +IP_ARGS = --run_default_mode_op +SYN_ARGS = --read_settings_files=on --write_settings_files=off +FIT_ARGS = --read_settings_files=on --write_settings_files=off +ASM_ARGS = --read_settings_files=on --write_settings_files=off +STA_ARGS = + +################################################################### +# Target implementations +################################################################### + +STAMP = echo done > + +define COPY_IP_RULE +$(patsubst %, ip/%, $(notdir $(1))): $(1) + @mkdir -p ip + @cp -pv $(1) ip/ +endef +$(foreach l,$(IP_FILES_REL) $(IP_TCL_FILES_REL),$(eval $(call COPY_IP_RULE,$(l)))) + +define TCL_IP_GEN_RULE +$(patsubst %.tcl, %.ip, $(1)): $(1) + cd ip && qsys-script --script=$(notdir $(1)) +endef +$(foreach l,$(IP_TCL_FILES_INT),$(eval $(call TCL_IP_GEN_RULE,$(l)))) + +%.ipregen.rpt: $(FPGA_TOP).qpf $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT) + quartus_ipgenerate $(IP_ARGS) $(FPGA_TOP) + +%.syn.rpt: syn.chg %.ipregen.rpt $(SYN_FILES_REL) + quartus_syn $(SYN_ARGS) $(FPGA_TOP) + +%.fit.rpt: fit.chg %.syn.rpt $(SDC_FILES_REL) + quartus_fit $(FIT_ARGS) $(FPGA_TOP) + +%.sta.rpt: sta.chg %.fit.rpt + quartus_sta $(STA_ARGS) $(FPGA_TOP) + +%.asm.rpt: asm.chg %.sta.rpt + quartus_asm $(ASM_ARGS) $(FPGA_TOP) + mkdir -p rev + EXT=sof; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $*.$$EXT rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + +%.sof: smart.log %.asm.rpt + + +smart.log: $(ASSIGNMENT_FILES) + quartus_sh --determine_smart_action $(FPGA_TOP) > smart.log + +################################################################### +# Project initialization +################################################################### + +$(ASSIGNMENT_FILES): $(QSF_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT) + rm -f $(FPGA_TOP).qsf + quartus_sh --prepare -f $(FPGA_FAMILY) -d $(FPGA_DEVICE) -t $(FPGA_TOP) $(FPGA_TOP) + echo >> $(FPGA_TOP).qsf + echo >> $(FPGA_TOP).qsf + echo "# Source files" >> $(FPGA_TOP).qsf + for x in $(SYN_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT); do \ + case $${x##*.} in \ + v|V) echo set_global_assignment -name VERILOG_FILE $$x >> $(FPGA_TOP).qsf ;;\ + vhd|VHD) echo set_global_assignment -name VHDL_FILE $$x >> $(FPGA_TOP).qsf ;;\ + qip|QIP) echo set_global_assignment -name QIP_FILE $$x >> $(FPGA_TOP).qsf ;;\ + ip|IP) echo set_global_assignment -name IP_FILE $$x >> $(FPGA_TOP).qsf ;;\ + *) echo set_global_assignment -name SOURCE_FILE $$x >> $(FPGA_TOP).qsf ;;\ + esac; \ + done + echo >> $(FPGA_TOP).qsf + echo "# SDC files" >> $(FPGA_TOP).qsf + for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE $$x >> $(FPGA_TOP).qsf; done + for x in $(QSF_FILES_REL); do printf "\n#\n# Included QSF file $$x\n#\n" >> $(FPGA_TOP).qsf; cat $$x >> $(FPGA_TOP).qsf; done + +syn.chg: + $(STAMP) syn.chg +fit.chg: + $(STAMP) fit.chg +sta.chg: + $(STAMP) sta.chg +asm.chg: + $(STAMP) asm.chg diff --git a/fpga/lib/pcie/example/520N_MX/fpga/fpga.qsf b/fpga/lib/pcie/example/520N_MX/fpga/fpga.qsf new file mode 100644 index 000000000..2d40df5e7 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/fpga.qsf @@ -0,0 +1,1033 @@ +# I/O constraints for the BittWare 520N-MX FPGA development board +# part: 1SM21CHU2F53E2VG + +set_global_assignment -name USE_CONF_DONE SDM_IO16 +set_global_assignment -name USE_INIT_DONE SDM_IO0 + +set_global_assignment -name USE_PWRMGT_SCL SDM_IO14 +set_global_assignment -name USE_PWRMGT_SDA SDM_IO11 +set_global_assignment -name USE_PWRMGT_ALERT SDM_IO12 +set_global_assignment -name PWRMGT_DEVICE_ADDRESS_IN_PMBUS_SLAVE_MODE 01 +set_global_assignment -name VID_OPERATION_MODE "PMBUS SLAVE" + +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 +set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION ON +set_global_assignment -name DEVICE_INITIALIZATION_CLOCK OSC_CLK_1_125MHZ +set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "AVST X16" +set_global_assignment -name ACTIVE_SERIAL_CLOCK AS_FREQ_100MHZ +set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_OCT_DONE OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name CONFIGURATION_VCCIO_LEVEL 1.8V +set_global_assignment -name USE_CHECKSUM_AS_USERCODE ON +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name ENABLE_ED_CRC_CHECK ON +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 +set_global_assignment -name MINIMUM_SEU_INTERVAL 0 + +set_global_assignment -name PRESERVE_UNUSED_XCVR_CHANNEL ON + +# Clock and reset +set_location_assignment PIN_BB20 -to "config_clk" + +set_location_assignment PIN_BE17 -to "usr_refclk0" +set_location_assignment PIN_BD17 -to "usr_refclk0(n)" + +set_location_assignment PIN_A24 -to "usr_refclk1" +set_location_assignment PIN_B23 -to "usr_refclk1(n)" + +set_location_assignment PIN_AW31 -to "mem0_refclk" +set_location_assignment PIN_AY31 -to "mem0_refclk(n)" + +set_location_assignment PIN_A42 -to "mem1_refclk" +set_location_assignment PIN_B41 -to "mem1_refclk(n)" + +set_location_assignment PIN_AU31 -to "esram_0_refclk" +set_location_assignment PIN_AU32 -to "esram_0_refclk(n)" + +set_location_assignment PIN_V31 -to "esram_1_refclk" +set_location_assignment PIN_U31 -to "esram_1_refclk(n)" + +set_location_assignment PIN_AR26 -to "hbm_bottom_refclk" +set_location_assignment PIN_AP26 -to "hbm_bottom_refclk(n)" + +set_location_assignment PIN_P27 -to "hbm_top_refclk" +set_location_assignment PIN_R27 -to "hbm_top_refclk(n)" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "config_clk" + +set_instance_assignment -name IO_STANDARD LVDS -to "usr_refclk0" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "usr_refclk0" + +set_instance_assignment -name IO_STANDARD LVDS -to "usr_refclk1" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "usr_refclk1" + +set_instance_assignment -name IO_STANDARD LVDS -to "esram_0_refclk" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "esram_0_refclk" + +set_instance_assignment -name IO_STANDARD LVDS -to "esram_1_refclk" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "esram_1_refclk" + +set_instance_assignment -name IO_STANDARD LVDS -to "hbm_bottom_refclk" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "hbm_bottom_refclk" + +set_instance_assignment -name IO_STANDARD LVDS -to "hbm_top_refclk" +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to "hbm_top_refclk" + +# LEDs +set_location_assignment PIN_AA39 -to "led_user_grn[0]" +set_location_assignment PIN_AL38 -to "led_user_grn[1]" + +set_location_assignment PIN_AA38 -to "led_user_red[0]" +set_location_assignment PIN_AL39 -to "led_user_red[1]" + +set_location_assignment PIN_AH39 -to "led_qsfp[0]" +set_location_assignment PIN_AJ39 -to "led_qsfp[1]" +set_location_assignment PIN_AK39 -to "led_qsfp[2]" +set_location_assignment PIN_AM38 -to "led_qsfp[3]" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "led_user_red[*]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "led_user_grn[*]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "led_qsfp[*]" + +set_instance_assignment -name IO_STANDARD "2.5 V" -to "led_user_red[*]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "led_user_grn[*]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "led_qsfp[*]" + +# UART +set_location_assignment PIN_BD12 -to "uart_tx" +set_location_assignment PIN_BE12 -to "uart_rx" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "uart_tx" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "uart_rx" + +# I2C +set_location_assignment PIN_BJ17 -to "fpga_i2c_sda" +set_location_assignment PIN_BJ18 -to "fpga_i2c_scl" +set_location_assignment PIN_BK17 -to "fpga_i2c_req_l" +set_location_assignment PIN_BK16 -to "fpga_i2c_mux_gnt" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_i2c_sda" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_i2c_scl" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_i2c_req_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_i2c_mux_gnt" + +# BMC SPI +set_location_assignment PIN_BK15 -to "bmc_spi_mosi" +set_location_assignment PIN_BF18 -to "bmc_spi_nss" +set_location_assignment PIN_BF19 -to "bmc_spi_sclk" +set_location_assignment PIN_BL15 -to "bmc_spi_miso" + +set_location_assignment PIN_BH20 -to "bmc_irq" + +set_location_assignment PIN_BH19 -to "fpga_gpio_1" +set_location_assignment PIN_BG20 -to "fpga_rst_n" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "bmc_spi_mosi" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "bmc_spi_nss" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "bmc_spi_sclk" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "bmc_spi_miso" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "bmc_irq" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_gpio_1" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "fpga_rst_n" + +# PCIe banks 1K 1L 1M +set_location_assignment PIN_AE51 -to "pcie_tx[0]" +set_location_assignment PIN_AE50 -to "pcie_tx[0](n)" +set_location_assignment PIN_AC47 -to "pcie_rx[0]" +set_location_assignment PIN_AC46 -to "pcie_rx[0](n)" +set_location_assignment PIN_AD49 -to "pcie_tx[1]" +set_location_assignment PIN_AD48 -to "pcie_tx[1](n)" +set_location_assignment PIN_AD45 -to "pcie_rx[1]" +set_location_assignment PIN_AD44 -to "pcie_rx[1](n)" +set_location_assignment PIN_AC51 -to "pcie_tx[2]" +set_location_assignment PIN_AC50 -to "pcie_tx[2](n)" +set_location_assignment PIN_AA47 -to "pcie_rx[2]" +set_location_assignment PIN_AA46 -to "pcie_rx[2](n)" +set_location_assignment PIN_AB49 -to "pcie_tx[3]" +set_location_assignment PIN_AB48 -to "pcie_tx[3](n)" +set_location_assignment PIN_AB45 -to "pcie_rx[3]" +set_location_assignment PIN_AB44 -to "pcie_rx[3](n)" +set_location_assignment PIN_AA51 -to "pcie_tx[4]" +set_location_assignment PIN_AA50 -to "pcie_tx[4](n)" +set_location_assignment PIN_W47 -to "pcie_rx[4]" +set_location_assignment PIN_W46 -to "pcie_rx[4](n)" +set_location_assignment PIN_Y49 -to "pcie_tx[5]" +set_location_assignment PIN_Y48 -to "pcie_tx[5](n)" +set_location_assignment PIN_Y45 -to "pcie_rx[5]" +set_location_assignment PIN_Y44 -to "pcie_rx[5](n)" +set_location_assignment PIN_W51 -to "pcie_tx[6]" +set_location_assignment PIN_W50 -to "pcie_tx[6](n)" +set_location_assignment PIN_U47 -to "pcie_rx[6]" +set_location_assignment PIN_U46 -to "pcie_rx[6](n)" +set_location_assignment PIN_V49 -to "pcie_tx[7]" +set_location_assignment PIN_V48 -to "pcie_tx[7](n)" +set_location_assignment PIN_V45 -to "pcie_rx[7]" +set_location_assignment PIN_V44 -to "pcie_rx[7](n)" +set_location_assignment PIN_U51 -to "pcie_tx[8]" +set_location_assignment PIN_U50 -to "pcie_tx[8](n)" +set_location_assignment PIN_R47 -to "pcie_rx[8]" +set_location_assignment PIN_R46 -to "pcie_rx[8](n)" +set_location_assignment PIN_T49 -to "pcie_tx[9]" +set_location_assignment PIN_T48 -to "pcie_tx[9](n)" +set_location_assignment PIN_T45 -to "pcie_rx[9]" +set_location_assignment PIN_T44 -to "pcie_rx[9](n)" +set_location_assignment PIN_R51 -to "pcie_tx[10]" +set_location_assignment PIN_R50 -to "pcie_tx[10](n)" +set_location_assignment PIN_N47 -to "pcie_rx[10]" +set_location_assignment PIN_N46 -to "pcie_rx[10](n)" +set_location_assignment PIN_P49 -to "pcie_tx[11]" +set_location_assignment PIN_P48 -to "pcie_tx[11](n)" +set_location_assignment PIN_P45 -to "pcie_rx[11]" +set_location_assignment PIN_P44 -to "pcie_rx[11](n)" +set_location_assignment PIN_N51 -to "pcie_tx[12]" +set_location_assignment PIN_N50 -to "pcie_tx[12](n)" +set_location_assignment PIN_L47 -to "pcie_rx[12]" +set_location_assignment PIN_L46 -to "pcie_rx[12](n)" +set_location_assignment PIN_M49 -to "pcie_tx[13]" +set_location_assignment PIN_M48 -to "pcie_tx[13](n)" +set_location_assignment PIN_M45 -to "pcie_rx[13]" +set_location_assignment PIN_M44 -to "pcie_rx[13](n)" +set_location_assignment PIN_L51 -to "pcie_tx[14]" +set_location_assignment PIN_L50 -to "pcie_tx[14](n)" +set_location_assignment PIN_J47 -to "pcie_rx[14]" +set_location_assignment PIN_J46 -to "pcie_rx[14](n)" +set_location_assignment PIN_K49 -to "pcie_tx[15]" +set_location_assignment PIN_K48 -to "pcie_tx[15](n)" +set_location_assignment PIN_K45 -to "pcie_rx[15]" +set_location_assignment PIN_K44 -to "pcie_rx[15](n)" + +set_location_assignment PIN_AC43 -to "pcie_refclk" +set_location_assignment PIN_AC42 -to "pcie_refclk(n)" + +set_location_assignment PIN_Y39 -to "pcie_perstn" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_rx[*]" + +set_instance_assignment -name IO_STANDARD "HCSL" -to "pcie_refclk" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "pcie_perstn" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "pcie_perstn" + +# QSFP + +# QSFP0 (bank 1D) +set_location_assignment PIN_BD49 -to "qsfp0_tx[0]" +set_location_assignment PIN_BD48 -to "qsfp0_tx[0](n)" +set_location_assignment PIN_BB45 -to "qsfp0_rx[0]" +set_location_assignment PIN_BB44 -to "qsfp0_rx[0](n)" +set_location_assignment PIN_BC51 -to "qsfp0_tx[1]" +set_location_assignment PIN_BC50 -to "qsfp0_tx[1](n)" +set_location_assignment PIN_BC47 -to "qsfp0_rx[1]" +set_location_assignment PIN_BC46 -to "qsfp0_rx[1](n)" +set_location_assignment PIN_BA51 -to "qsfp0_tx[2]" +set_location_assignment PIN_BA50 -to "qsfp0_tx[2](n)" +set_location_assignment PIN_AY45 -to "qsfp0_rx[2]" +set_location_assignment PIN_AY44 -to "qsfp0_rx[2](n)" +set_location_assignment PIN_AY49 -to "qsfp0_tx[3]" +set_location_assignment PIN_AY48 -to "qsfp0_tx[3](n)" +set_location_assignment PIN_AW47 -to "qsfp0_rx[3]" +set_location_assignment PIN_AW46 -to "qsfp0_rx[3](n)" +set_location_assignment PIN_AU43 -to "qsfp0_refclk" +set_location_assignment PIN_AU42 -to "qsfp0_refclk(n)" +set_location_assignment PIN_AR43 -to "qsfp0_rcvrd_refclk" +set_location_assignment PIN_AR42 -to "qsfp0_rcvrd_refclk(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp0_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp0_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp0_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp0_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp0_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp0_refclk" +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp0_rcvrd_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp0_rcvrd_refclk" + +# QSFP1 (bank 1E) +set_location_assignment PIN_AV49 -to "qsfp1_tx[0]" +set_location_assignment PIN_AV48 -to "qsfp1_tx[0](n)" +set_location_assignment PIN_AU47 -to "qsfp1_rx[0]" +set_location_assignment PIN_AU46 -to "qsfp1_rx[0](n)" +set_location_assignment PIN_AU51 -to "qsfp1_tx[1]" +set_location_assignment PIN_AU50 -to "qsfp1_tx[1](n)" +set_location_assignment PIN_AT45 -to "qsfp1_rx[1]" +set_location_assignment PIN_AT44 -to "qsfp1_rx[1](n)" +set_location_assignment PIN_AR51 -to "qsfp1_tx[2]" +set_location_assignment PIN_AR50 -to "qsfp1_tx[2](n)" +set_location_assignment PIN_AP45 -to "qsfp1_rx[2]" +set_location_assignment PIN_AP44 -to "qsfp1_rx[2](n)" +set_location_assignment PIN_AM49 -to "qsfp1_tx[3]" +set_location_assignment PIN_AM48 -to "qsfp1_tx[3](n)" +set_location_assignment PIN_AL47 -to "qsfp1_rx[3]" +set_location_assignment PIN_AL46 -to "qsfp1_rx[3](n)" +set_location_assignment PIN_AN43 -to "qsfp1_refclk" +set_location_assignment PIN_AN42 -to "qsfp1_refclk(n)" +set_location_assignment PIN_AL43 -to "qsfp1_rcvrd_refclk" +set_location_assignment PIN_AL42 -to "qsfp1_rcvrd_refclk(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp1_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp1_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp1_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp1_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp1_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp1_refclk" +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp1_rcvrd_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp1_rcvrd_refclk" + +# QSFP2 (bank 1F, hard 100G MAC) +set_location_assignment PIN_AN51 -to "qsfp2_tx[0]" +set_location_assignment PIN_AN50 -to "qsfp2_tx[0](n)" +set_location_assignment PIN_AM45 -to "qsfp2_rx[0]" +set_location_assignment PIN_AM44 -to "qsfp2_rx[0](n)" +set_location_assignment PIN_AL51 -to "qsfp2_tx[1]" +set_location_assignment PIN_AL50 -to "qsfp2_tx[1](n)" +set_location_assignment PIN_AK45 -to "qsfp2_rx[1]" +set_location_assignment PIN_AK44 -to "qsfp2_rx[1](n)" +set_location_assignment PIN_AJ51 -to "qsfp2_tx[2]" +set_location_assignment PIN_AJ50 -to "qsfp2_tx[2](n)" +set_location_assignment PIN_AH45 -to "qsfp2_rx[2]" +set_location_assignment PIN_AH44 -to "qsfp2_rx[2](n)" +set_location_assignment PIN_AG51 -to "qsfp2_tx[3]" +set_location_assignment PIN_AG50 -to "qsfp2_tx[3](n)" +set_location_assignment PIN_AF45 -to "qsfp2_rx[3]" +set_location_assignment PIN_AF44 -to "qsfp2_rx[3](n)" +set_location_assignment PIN_AJ43 -to "qsfp2_refclk" +set_location_assignment PIN_AJ42 -to "qsfp2_refclk(n)" +set_location_assignment PIN_AG43 -to "qsfp2_rcvrd_refclk" +set_location_assignment PIN_AG42 -to "qsfp2_rcvrd_refclk(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp2_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp2_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp2_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp2_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp2_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp2_refclk" +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp2_rcvrd_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp2_rcvrd_refclk" + +# QSFP3 (bank 1N, hard 100G MAC) +set_location_assignment PIN_J51 -to "qsfp3_tx[0]" +set_location_assignment PIN_J50 -to "qsfp3_tx[0](n)" +set_location_assignment PIN_H45 -to "qsfp3_rx[0]" +set_location_assignment PIN_H44 -to "qsfp3_rx[0](n)" +set_location_assignment PIN_G51 -to "qsfp3_tx[1]" +set_location_assignment PIN_G50 -to "qsfp3_tx[1](n)" +set_location_assignment PIN_F45 -to "qsfp3_rx[1]" +set_location_assignment PIN_F44 -to "qsfp3_rx[1](n)" +set_location_assignment PIN_E51 -to "qsfp3_tx[2]" +set_location_assignment PIN_D51 -to "qsfp3_tx[2](n)" +set_location_assignment PIN_D45 -to "qsfp3_rx[2]" +set_location_assignment PIN_D44 -to "qsfp3_rx[2](n)" +set_location_assignment PIN_C50 -to "qsfp3_tx[3]" +set_location_assignment PIN_B50 -to "qsfp3_tx[3](n)" +set_location_assignment PIN_B44 -to "qsfp3_rx[3]" +set_location_assignment PIN_A44 -to "qsfp3_rx[3](n)" +set_location_assignment PIN_N43 -to "qsfp3_refclk" +set_location_assignment PIN_N42 -to "qsfp3_refclk(n)" +set_location_assignment PIN_L43 -to "qsfp3_rcvrd_refclk" +set_location_assignment PIN_L42 -to "qsfp3_rcvrd_refclk(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp3_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp3_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp3_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp3_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp3_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp3_refclk" +set_instance_assignment -name IO_STANDARD LVDS -to "qsfp3_rcvrd_refclk" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "qsfp3_rcvrd_refclk" + +set_location_assignment PIN_H19 -to "qsfp_irq_n[0]" +set_location_assignment PIN_H18 -to "qsfp_irq_n[1]" +set_location_assignment PIN_A22 -to "qsfp_irq_n[2]" +set_location_assignment PIN_C23 -to "qsfp_irq_n[3]" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp_irq_n[*]" + +# OCuLink + +# OCuLink 0 (J26, PCIe, banks 4C, 4D) +set_location_assignment PIN_BL5 -to "oc0_tx[0]" +set_location_assignment PIN_BL6 -to "oc0_tx[0](n)" +set_location_assignment PIN_BH7 -to "oc0_rx[0]" +set_location_assignment PIN_BH8 -to "oc0_rx[0](n)" +set_location_assignment PIN_BK3 -to "oc0_tx[1]" +set_location_assignment PIN_BK4 -to "oc0_tx[1](n)" +set_location_assignment PIN_BJ5 -to "oc0_rx[1]" +set_location_assignment PIN_BJ6 -to "oc0_rx[1](n)" +set_location_assignment PIN_BH3 -to "oc0_tx[2]" +set_location_assignment PIN_BH4 -to "oc0_tx[2](n)" +set_location_assignment PIN_BG5 -to "oc0_rx[2]" +set_location_assignment PIN_BG6 -to "oc0_rx[2](n)" +set_location_assignment PIN_BG1 -to "oc0_tx[3]" +set_location_assignment PIN_BG2 -to "oc0_tx[3](n)" +set_location_assignment PIN_BF7 -to "oc0_rx[3]" +set_location_assignment PIN_BF8 -to "oc0_rx[3](n)" +set_location_assignment PIN_BF3 -to "oc0_tx[4]" +set_location_assignment PIN_BF4 -to "oc0_tx[4](n)" +set_location_assignment PIN_BE5 -to "oc0_rx[4]" +set_location_assignment PIN_BE6 -to "oc0_rx[4](n)" +set_location_assignment PIN_BE1 -to "oc0_tx[5]" +set_location_assignment PIN_BE2 -to "oc0_tx[5](n)" +set_location_assignment PIN_BD7 -to "oc0_rx[5]" +set_location_assignment PIN_BD8 -to "oc0_rx[5](n)" +set_location_assignment PIN_BD3 -to "oc0_tx[6]" +set_location_assignment PIN_BD4 -to "oc0_tx[6](n)" +set_location_assignment PIN_BB7 -to "oc0_rx[6]" +set_location_assignment PIN_BB8 -to "oc0_rx[6](n)" +set_location_assignment PIN_BC1 -to "oc0_tx[7]" +set_location_assignment PIN_BC2 -to "oc0_tx[7](n)" +set_location_assignment PIN_BC5 -to "oc0_rx[7]" +set_location_assignment PIN_BC6 -to "oc0_rx[7](n)" +set_location_assignment PIN_AW9 -to "oc0_refclk_1" +set_location_assignment PIN_AW10 -to "oc0_refclk_1(n)" +set_location_assignment PIN_BA9 -to "oc0_refclk_2" +set_location_assignment PIN_BA10 -to "oc0_refclk_2(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc0_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc0_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc0_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc0_rx[*]" + +set_instance_assignment -name IO_STANDARD "HCSL" -to "oc0_refclk_1" +set_instance_assignment -name IO_STANDARD "HCSL" -to "oc0_refclk_2" + +set_location_assignment PIN_BL10 -to "oc0_gpio[0]" +set_location_assignment PIN_BH10 -to "oc0_gpio[1]" +set_location_assignment PIN_BG10 -to "oc0_gpio[2]" +set_location_assignment PIN_BF10 -to "oc0_gpio[3]" +set_location_assignment PIN_AT15 -to "oc0_gpio[4]" +set_location_assignment PIN_AR15 -to "oc0_gpio[5]" +set_location_assignment PIN_AV15 -to "oc0_gpio[6]" +set_location_assignment PIN_AU15 -to "oc0_gpio[7]" +set_location_assignment PIN_AW14 -to "oc0_gpio[8]" +set_location_assignment PIN_AV14 -to "oc0_gpio[9]" +set_location_assignment PIN_AY14 -to "oc0_gpio[10]" +set_location_assignment PIN_BA14 -to "oc0_gpio[11]" +set_location_assignment PIN_BB15 -to "oc0_gpio[12]" +set_location_assignment PIN_BA15 -to "oc0_gpio[13]" +set_location_assignment PIN_BC14 -to "oc0_gpio[14]" +set_location_assignment PIN_BC15 -to "oc0_gpio[15]" + +set_location_assignment PIN_BE10 -to "oc0_gpio_dir[0]" +set_location_assignment PIN_BD10 -to "oc0_gpio_dir[1]" +set_location_assignment PIN_BC10 -to "oc0_gpio_dir[2]" +set_location_assignment PIN_AP39 -to "oc0_gpio_dir[3]" +set_location_assignment PIN_BF14 -to "oc0_gpio_dir[4]" +set_location_assignment PIN_BF13 -to "oc0_gpio_dir[5]" +set_location_assignment PIN_BH13 -to "oc0_gpio_dir[6]" +set_location_assignment PIN_BG13 -to "oc0_gpio_dir[7]" +set_location_assignment PIN_BJ13 -to "oc0_gpio_dir[8]" +set_location_assignment PIN_BJ12 -to "oc0_gpio_dir[9]" +set_location_assignment PIN_BJ14 -to "oc0_gpio_dir[10]" +set_location_assignment PIN_BK14 -to "oc0_gpio_dir[11]" +set_location_assignment PIN_BL14 -to "oc0_gpio_dir[12]" +set_location_assignment PIN_BL13 -to "oc0_gpio_dir[13]" +set_location_assignment PIN_AU17 -to "oc0_gpio_dir[14]" +set_location_assignment PIN_AU16 -to "oc0_gpio_dir[15]" + +set_location_assignment PIN_AW17 -to "oc0_buff_en_n[0]" +set_location_assignment PIN_AY17 -to "oc0_buff_en_n[1]" +set_location_assignment PIN_AW16 -to "oc0_buff_en_n[2]" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio[0]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio[1]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio[2]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio[3]" + +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio[0]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio[1]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio[2]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio[3]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[4]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[5]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[6]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[7]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[8]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[9]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[10]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[11]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[12]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[13]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[14]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio[15]" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio_dir[0]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio_dir[1]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio_dir[2]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc0_gpio_dir[3]" + +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio_dir[0]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio_dir[1]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio_dir[2]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc0_gpio_dir[3]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[4]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[5]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[6]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[7]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[8]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[9]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[10]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[11]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[12]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[13]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[14]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_gpio_dir[15]" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc0_buff_en_n[*]" + +# OCuLink 1 (J27, PCIe, banks 4K, 4L) +set_location_assignment PIN_AF3 -to "oc1_tx[0]" +set_location_assignment PIN_AF4 -to "oc1_tx[0](n)" +set_location_assignment PIN_AE5 -to "oc1_rx[0]" +set_location_assignment PIN_AE6 -to "oc1_rx[0](n)" +set_location_assignment PIN_AE1 -to "oc1_tx[1]" +set_location_assignment PIN_AE2 -to "oc1_tx[1](n)" +set_location_assignment PIN_AD7 -to "oc1_rx[1]" +set_location_assignment PIN_AD8 -to "oc1_rx[1](n)" +set_location_assignment PIN_AD3 -to "oc1_tx[2]" +set_location_assignment PIN_AD4 -to "oc1_tx[2](n)" +set_location_assignment PIN_AC5 -to "oc1_rx[2]" +set_location_assignment PIN_AC6 -to "oc1_rx[2](n)" +set_location_assignment PIN_AC1 -to "oc1_tx[3]" +set_location_assignment PIN_AC2 -to "oc1_tx[3](n)" +set_location_assignment PIN_AB7 -to "oc1_rx[3]" +set_location_assignment PIN_AB8 -to "oc1_rx[3](n)" +set_location_assignment PIN_AB3 -to "oc1_tx[4]" +set_location_assignment PIN_AB4 -to "oc1_tx[4](n)" +set_location_assignment PIN_AA5 -to "oc1_rx[4]" +set_location_assignment PIN_AA6 -to "oc1_rx[4](n)" +set_location_assignment PIN_AA1 -to "oc1_tx[5]" +set_location_assignment PIN_AA2 -to "oc1_tx[5](n)" +set_location_assignment PIN_Y7 -to "oc1_rx[5]" +set_location_assignment PIN_Y8 -to "oc1_rx[5](n)" +set_location_assignment PIN_Y3 -to "oc1_tx[6]" +set_location_assignment PIN_Y4 -to "oc1_tx[6](n)" +set_location_assignment PIN_W5 -to "oc1_rx[6]" +set_location_assignment PIN_W6 -to "oc1_rx[6](n)" +set_location_assignment PIN_W1 -to "oc1_tx[7]" +set_location_assignment PIN_W2 -to "oc1_tx[7](n)" +set_location_assignment PIN_V7 -to "oc1_rx[7]" +set_location_assignment PIN_V8 -to "oc1_rx[7](n)" +set_location_assignment PIN_AC9 -to "oc1_refclk_1" +set_location_assignment PIN_AC10 -to "oc1_refclk_1(n)" +set_location_assignment PIN_AE9 -to "oc1_refclk_2" +set_location_assignment PIN_AE10 -to "oc1_refclk_2(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc1_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc1_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc1_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc1_rx[*]" + +set_instance_assignment -name IO_STANDARD "HCSL" -to "oc1_refclk_1" +set_instance_assignment -name IO_STANDARD "HCSL" -to "oc1_refclk_2" + +set_location_assignment PIN_AG13 -to "oc1_gpio[0]" +set_location_assignment PIN_AL13 -to "oc1_gpio[1]" +set_location_assignment PIN_AM13 -to "oc1_gpio[2]" +set_location_assignment PIN_AN13 -to "oc1_gpio[3]" +set_location_assignment PIN_C16 -to "oc1_gpio[4]" +set_location_assignment PIN_D16 -to "oc1_gpio[5]" +set_location_assignment PIN_B15 -to "oc1_gpio[6]" +set_location_assignment PIN_B16 -to "oc1_gpio[7]" +set_location_assignment PIN_C14 -to "oc1_gpio[8]" +set_location_assignment PIN_C15 -to "oc1_gpio[9]" +set_location_assignment PIN_A14 -to "oc1_gpio[10]" +set_location_assignment PIN_A15 -to "oc1_gpio[11]" +set_location_assignment PIN_E15 -to "oc1_gpio[12]" +set_location_assignment PIN_F15 -to "oc1_gpio[13]" +set_location_assignment PIN_H15 -to "oc1_gpio[14]" +set_location_assignment PIN_G15 -to "oc1_gpio[15]" + +set_location_assignment PIN_AH13 -to "oc1_gpio_dir[0]" +set_location_assignment PIN_AP13 -to "oc1_gpio_dir[1]" +set_location_assignment PIN_AF13 -to "oc1_gpio_dir[2]" +set_location_assignment PIN_AC38 -to "oc1_gpio_dir[3]" +set_location_assignment PIN_J16 -to "oc1_gpio_dir[4]" +set_location_assignment PIN_K16 -to "oc1_gpio_dir[5]" +set_location_assignment PIN_L15 -to "oc1_gpio_dir[6]" +set_location_assignment PIN_K15 -to "oc1_gpio_dir[7]" +set_location_assignment PIN_M15 -to "oc1_gpio_dir[8]" +set_location_assignment PIN_N15 -to "oc1_gpio_dir[9]" +set_location_assignment PIN_M16 -to "oc1_gpio_dir[10]" +set_location_assignment PIN_N16 -to "oc1_gpio_dir[11]" +set_location_assignment PIN_P16 -to "oc1_gpio_dir[12]" +set_location_assignment PIN_R16 -to "oc1_gpio_dir[13]" +set_location_assignment PIN_A13 -to "oc1_gpio_dir[14]" +set_location_assignment PIN_A12 -to "oc1_gpio_dir[15]" + +set_location_assignment PIN_B13 -to "oc1_buff_en_n[0]" +set_location_assignment PIN_C13 -to "oc1_buff_en_n[1]" +set_location_assignment PIN_B12 -to "oc1_buff_en_n[2]" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio[0]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio[1]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio[2]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio[3]" + +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio[0]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio[1]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio[2]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio[3]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[4]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[5]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[6]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[7]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[8]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[9]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[10]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[11]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[12]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[13]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[14]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio[15]" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio_dir[0]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio_dir[1]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio_dir[2]" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc1_gpio_dir[3]" + +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio_dir[0]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio_dir[1]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio_dir[2]" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc1_gpio_dir[3]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[4]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[5]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[6]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[7]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[8]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[9]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[10]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[11]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[12]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[13]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[14]" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_gpio_dir[15]" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "oc1_buff_en_n[*]" + +# OCuLink 2 (J22, 25G, banks 4N, 4M) +set_location_assignment PIN_P3 -to "oc2_tx[0]" +set_location_assignment PIN_P4 -to "oc2_tx[0](n)" +set_location_assignment PIN_N5 -to "oc2_rx[0]" +set_location_assignment PIN_N6 -to "oc2_rx[0](n)" +set_location_assignment PIN_N1 -to "oc2_tx[1]" +set_location_assignment PIN_N2 -to "oc2_tx[1](n)" +set_location_assignment PIN_M7 -to "oc2_rx[1]" +set_location_assignment PIN_M8 -to "oc2_rx[1](n)" +set_location_assignment PIN_L1 -to "oc2_tx[2]" +set_location_assignment PIN_L2 -to "oc2_tx[2](n)" +set_location_assignment PIN_K7 -to "oc2_rx[2]" +set_location_assignment PIN_K8 -to "oc2_rx[2](n)" +set_location_assignment PIN_K3 -to "oc2_tx[3]" +set_location_assignment PIN_K4 -to "oc2_tx[3](n)" +set_location_assignment PIN_J5 -to "oc2_rx[3]" +set_location_assignment PIN_J6 -to "oc2_rx[3](n)" +set_location_assignment PIN_H3 -to "oc2_tx[4]" +set_location_assignment PIN_H4 -to "oc2_tx[4](n)" +set_location_assignment PIN_G5 -to "oc2_rx[4]" +set_location_assignment PIN_G6 -to "oc2_rx[4](n)" +set_location_assignment PIN_G1 -to "oc2_tx[5]" +set_location_assignment PIN_G2 -to "oc2_tx[5](n)" +set_location_assignment PIN_F7 -to "oc2_rx[5]" +set_location_assignment PIN_F8 -to "oc2_rx[5](n)" +set_location_assignment PIN_E1 -to "oc2_tx[6]" +set_location_assignment PIN_E2 -to "oc2_tx[6](n)" +set_location_assignment PIN_D7 -to "oc2_rx[6]" +set_location_assignment PIN_D8 -to "oc2_rx[6](n)" +set_location_assignment PIN_D3 -to "oc2_tx[7]" +set_location_assignment PIN_D4 -to "oc2_tx[7](n)" +set_location_assignment PIN_C5 -to "oc2_rx[7]" +set_location_assignment PIN_C6 -to "oc2_rx[7](n)" +set_location_assignment PIN_R9 -to "oc2_refclk_1" +set_location_assignment PIN_R10 -to "oc2_refclk_1(n)" +set_location_assignment PIN_L9 -to "oc2_refclk_2" +set_location_assignment PIN_L10 -to "oc2_refclk_2(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc2_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc2_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc2_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc2_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "oc2_refclk_1" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "oc2_refclk_1" +set_instance_assignment -name IO_STANDARD LVDS -to "oc2_refclk_2" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "oc2_refclk_2" + +set_location_assignment PIN_AJ13 -to "oc2_perst_n" +set_location_assignment PIN_AC39 -to "oc2_buff_in_sel" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc2_perst_n" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc2_perst_n" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc2_buff_in_sel" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc2_buff_in_sel" + +# OCuLink 3 (J23, 25G, banks 4E, 4F) +set_location_assignment PIN_AV3 -to "oc3_tx[0]" +set_location_assignment PIN_AV4 -to "oc3_tx[0](n)" +set_location_assignment PIN_AU5 -to "oc3_rx[0]" +set_location_assignment PIN_AU6 -to "oc3_rx[0](n)" +set_location_assignment PIN_AU1 -to "oc3_tx[1]" +set_location_assignment PIN_AU2 -to "oc3_tx[1](n)" +set_location_assignment PIN_AT7 -to "oc3_rx[1]" +set_location_assignment PIN_AT8 -to "oc3_rx[1](n)" +set_location_assignment PIN_AR1 -to "oc3_tx[2]" +set_location_assignment PIN_AR2 -to "oc3_tx[2](n)" +set_location_assignment PIN_AP7 -to "oc3_rx[2]" +set_location_assignment PIN_AP8 -to "oc3_rx[2](n)" +set_location_assignment PIN_AP3 -to "oc3_tx[3]" +set_location_assignment PIN_AP4 -to "oc3_tx[3](n)" +set_location_assignment PIN_AN5 -to "oc3_rx[3]" +set_location_assignment PIN_AN6 -to "oc3_rx[3](n)" +set_location_assignment PIN_AM3 -to "oc3_tx[4]" +set_location_assignment PIN_AM4 -to "oc3_tx[4](n)" +set_location_assignment PIN_AL5 -to "oc3_rx[4]" +set_location_assignment PIN_AL6 -to "oc3_rx[4](n)" +set_location_assignment PIN_AL1 -to "oc3_tx[5]" +set_location_assignment PIN_AL2 -to "oc3_tx[5](n)" +set_location_assignment PIN_AK7 -to "oc3_rx[5]" +set_location_assignment PIN_AK8 -to "oc3_rx[5](n)" +set_location_assignment PIN_AJ1 -to "oc3_tx[6]" +set_location_assignment PIN_AJ2 -to "oc3_tx[6](n)" +set_location_assignment PIN_AH7 -to "oc3_rx[6]" +set_location_assignment PIN_AH8 -to "oc3_rx[6](n)" +set_location_assignment PIN_AH3 -to "oc3_tx[7]" +set_location_assignment PIN_AH4 -to "oc3_tx[7](n)" +set_location_assignment PIN_AG5 -to "oc3_rx[7]" +set_location_assignment PIN_AG6 -to "oc3_rx[7](n)" +set_location_assignment PIN_AL9 -to "oc3_refclk_1" +set_location_assignment PIN_AL10 -to "oc3_refclk_1(n)" +set_location_assignment PIN_AG9 -to "oc3_refclk_2" +set_location_assignment PIN_AG10 -to "oc3_refclk_2(n)" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc3_tx[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "oc3_rx[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc3_tx[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "oc3_rx[*]" + +set_instance_assignment -name IO_STANDARD LVDS -to "oc3_refclk_1" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "oc3_refclk_1" +set_instance_assignment -name IO_STANDARD LVDS -to "oc3_refclk_2" +set_instance_assignment -name XCVR_S10_REFCLK_TERM_TRISTATE TRISTATE_OFF -to "oc3_refclk_2" + +set_location_assignment PIN_BK10 -to "oc3_perst_n" +set_location_assignment PIN_AN39 -to "oc3_buff_in_sel" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc3_perst_n" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc3_perst_n" + +set_instance_assignment -name USE_AS_3V_GPIO ON -to "oc3_buff_in_sel" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "oc3_buff_in_sel" + +# DDR4 module 0 +set_location_assignment PIN_BA33 -to "mem0_rzq" + +set_location_assignment PIN_BC31 -to "mem0_alert_n" +set_location_assignment PIN_AW33 -to "mem0_reset_n" +set_location_assignment PIN_BH35 -to "mem0_par" + +set_location_assignment PIN_BL34 -to "mem0_a[0]" +set_location_assignment PIN_BK34 -to "mem0_a[1]" +set_location_assignment PIN_BJ34 -to "mem0_a[2]" +set_location_assignment PIN_BH34 -to "mem0_a[3]" +set_location_assignment PIN_BH33 -to "mem0_a[4]" +set_location_assignment PIN_BJ33 -to "mem0_a[5]" +set_location_assignment PIN_BK35 -to "mem0_a[6]" +set_location_assignment PIN_BL35 -to "mem0_a[7]" +set_location_assignment PIN_BD33 -to "mem0_a[8]" +set_location_assignment PIN_BC33 -to "mem0_a[9]" +set_location_assignment PIN_BG33 -to "mem0_a[10]" +set_location_assignment PIN_BF33 -to "mem0_a[11]" +set_location_assignment PIN_BB33 -to "mem0_a[12]" +set_location_assignment PIN_BB32 -to "mem0_a[13]" +set_location_assignment PIN_BA32 -to "mem0_a[14]" +set_location_assignment PIN_AW32 -to "mem0_a[15]" +set_location_assignment PIN_AY32 -to "mem0_a[16]" +set_location_assignment PIN_BD32 -to "mem0_bg[0]" +set_location_assignment PIN_AV33 -to "mem0_bg[1]" +set_location_assignment PIN_AV34 -to "mem0_act_n" +set_location_assignment PIN_BA34 -to "mem0_odt[0]" +set_location_assignment PIN_AY34 -to "mem0_odt[1]" +set_location_assignment PIN_BF34 -to "mem0_ck_p[0]" +set_location_assignment PIN_BE34 -to "mem0_ck_n[0]" +set_location_assignment PIN_AW34 -to "mem0_cs_n[0]" +set_location_assignment PIN_BG35 -to "mem0_cs_n[1]" +set_location_assignment PIN_BD34 -to "mem0_cke[0]" +set_location_assignment PIN_BC34 -to "mem0_cke[1]" +set_location_assignment PIN_BF32 -to "mem0_ba[0]" +set_location_assignment PIN_BE32 -to "mem0_ba[1]" + +set_location_assignment PIN_BF23 -to "mem0_dqs_p[0]" +set_location_assignment PIN_BG23 -to "mem0_dqs_n[0]" +set_location_assignment PIN_BJ22 -to "mem0_dqs_p[1]" +set_location_assignment PIN_BK22 -to "mem0_dqs_n[1]" +set_location_assignment PIN_BC26 -to "mem0_dqs_p[2]" +set_location_assignment PIN_BD26 -to "mem0_dqs_n[2]" +set_location_assignment PIN_BG25 -to "mem0_dqs_p[3]" +set_location_assignment PIN_BF25 -to "mem0_dqs_n[3]" +set_location_assignment PIN_BK26 -to "mem0_dqs_p[4]" +set_location_assignment PIN_BK25 -to "mem0_dqs_n[4]" +set_location_assignment PIN_BK24 -to "mem0_dqs_p[5]" +set_location_assignment PIN_BJ24 -to "mem0_dqs_n[5]" +set_location_assignment PIN_BJ28 -to "mem0_dqs_p[6]" +set_location_assignment PIN_BH28 -to "mem0_dqs_n[6]" +set_location_assignment PIN_BK27 -to "mem0_dqs_p[7]" +set_location_assignment PIN_BJ27 -to "mem0_dqs_n[7]" +set_location_assignment PIN_BF29 -to "mem0_dqs_p[8]" +set_location_assignment PIN_BE29 -to "mem0_dqs_n[8]" +set_location_assignment PIN_BA28 -to "mem0_dqs_p[9]" +set_location_assignment PIN_BA29 -to "mem0_dqs_n[9]" +set_location_assignment PIN_BB30 -to "mem0_dqs_p[10]" +set_location_assignment PIN_BC30 -to "mem0_dqs_n[10]" +set_location_assignment PIN_BH30 -to "mem0_dqs_p[11]" +set_location_assignment PIN_BG30 -to "mem0_dqs_n[11]" +set_location_assignment PIN_BK39 -to "mem0_dqs_p[12]" +set_location_assignment PIN_BL39 -to "mem0_dqs_n[12]" +set_location_assignment PIN_BG40 -to "mem0_dqs_p[13]" +set_location_assignment PIN_BH40 -to "mem0_dqs_n[13]" +set_location_assignment PIN_BH38 -to "mem0_dqs_p[14]" +set_location_assignment PIN_BJ38 -to "mem0_dqs_n[14]" +set_location_assignment PIN_BC38 -to "mem0_dqs_p[15]" +set_location_assignment PIN_BD38 -to "mem0_dqs_n[15]" +set_location_assignment PIN_BA37 -to "mem0_dqs_p[16]" +set_location_assignment PIN_BB37 -to "mem0_dqs_n[16]" +set_location_assignment PIN_BG37 -to "mem0_dqs_p[17]" +set_location_assignment PIN_BF37 -to "mem0_dqs_n[17]" + +set_location_assignment PIN_BE24 -to "mem0_dq[0]" +set_location_assignment PIN_BF24 -to "mem0_dq[1]" +set_location_assignment PIN_BH24 -to "mem0_dq[2]" +set_location_assignment PIN_BH25 -to "mem0_dq[3]" +set_location_assignment PIN_BL23 -to "mem0_dq[4]" +set_location_assignment PIN_BL22 -to "mem0_dq[5]" +set_location_assignment PIN_BJ23 -to "mem0_dq[6]" +set_location_assignment PIN_BH23 -to "mem0_dq[7]" +set_location_assignment PIN_AW28 -to "mem0_dq[8]" +set_location_assignment PIN_AW27 -to "mem0_dq[9]" +set_location_assignment PIN_AY27 -to "mem0_dq[10]" +set_location_assignment PIN_BA27 -to "mem0_dq[11]" +set_location_assignment PIN_BE26 -to "mem0_dq[12]" +set_location_assignment PIN_BE25 -to "mem0_dq[13]" +set_location_assignment PIN_BB26 -to "mem0_dq[14]" +set_location_assignment PIN_BB27 -to "mem0_dq[15]" +set_location_assignment PIN_BE27 -to "mem0_dq[16]" +set_location_assignment PIN_BF27 -to "mem0_dq[17]" +set_location_assignment PIN_BG26 -to "mem0_dq[18]" +set_location_assignment PIN_BG27 -to "mem0_dq[19]" +set_location_assignment PIN_BL25 -to "mem0_dq[20]" +set_location_assignment PIN_BL24 -to "mem0_dq[21]" +set_location_assignment PIN_BJ26 -to "mem0_dq[22]" +set_location_assignment PIN_BH26 -to "mem0_dq[23]" +set_location_assignment PIN_BC28 -to "mem0_dq[24]" +set_location_assignment PIN_BB28 -to "mem0_dq[25]" +set_location_assignment PIN_BD28 -to "mem0_dq[26]" +set_location_assignment PIN_BD27 -to "mem0_dq[27]" +set_location_assignment PIN_BL28 -to "mem0_dq[28]" +set_location_assignment PIN_BL27 -to "mem0_dq[29]" +set_location_assignment PIN_BG28 -to "mem0_dq[30]" +set_location_assignment PIN_BF28 -to "mem0_dq[31]" +set_location_assignment PIN_BK30 -to "mem0_dq[32]" +set_location_assignment PIN_BL30 -to "mem0_dq[33]" +set_location_assignment PIN_BK29 -to "mem0_dq[34]" +set_location_assignment PIN_BL29 -to "mem0_dq[35]" +set_location_assignment PIN_BD29 -to "mem0_dq[36]" +set_location_assignment PIN_BC29 -to "mem0_dq[37]" +set_location_assignment PIN_BJ29 -to "mem0_dq[38]" +set_location_assignment PIN_BH29 -to "mem0_dq[39]" +set_location_assignment PIN_AV30 -to "mem0_dq[40]" +set_location_assignment PIN_AV29 -to "mem0_dq[41]" +set_location_assignment PIN_AW29 -to "mem0_dq[42]" +set_location_assignment PIN_AY29 -to "mem0_dq[43]" +set_location_assignment PIN_BF30 -to "mem0_dq[44]" +set_location_assignment PIN_BE30 -to "mem0_dq[45]" +set_location_assignment PIN_AY30 -to "mem0_dq[46]" +set_location_assignment PIN_BA30 -to "mem0_dq[47]" +set_location_assignment PIN_BJ39 -to "mem0_dq[48]" +set_location_assignment PIN_BH39 -to "mem0_dq[49]" +set_location_assignment PIN_BF39 -to "mem0_dq[50]" +set_location_assignment PIN_BE39 -to "mem0_dq[51]" +set_location_assignment PIN_BE40 -to "mem0_dq[52]" +set_location_assignment PIN_BF40 -to "mem0_dq[53]" +set_location_assignment PIN_BK40 -to "mem0_dq[54]" +set_location_assignment PIN_BL40 -to "mem0_dq[55]" +set_location_assignment PIN_BL37 -to "mem0_dq[56]" +set_location_assignment PIN_BL38 -to "mem0_dq[57]" +set_location_assignment PIN_BJ37 -to "mem0_dq[58]" +set_location_assignment PIN_BK37 -to "mem0_dq[59]" +set_location_assignment PIN_BC39 -to "mem0_dq[60]" +set_location_assignment PIN_BD39 -to "mem0_dq[61]" +set_location_assignment PIN_BF38 -to "mem0_dq[62]" +set_location_assignment PIN_BG38 -to "mem0_dq[63]" +set_location_assignment PIN_BC36 -to "mem0_dq[64]" +set_location_assignment PIN_BB36 -to "mem0_dq[65]" +set_location_assignment PIN_AY36 -to "mem0_dq[66]" +set_location_assignment PIN_AW36 -to "mem0_dq[67]" +set_location_assignment PIN_BD37 -to "mem0_dq[68]" +set_location_assignment PIN_BE37 -to "mem0_dq[69]" +set_location_assignment PIN_AW37 -to "mem0_dq[70]" +set_location_assignment PIN_AY37 -to "mem0_dq[71]" + +# DDR4 module 1 +set_location_assignment PIN_A40 -to "mem1_rzq" + +set_location_assignment PIN_P36 -to "mem1_alert_n" +set_location_assignment PIN_F35 -to "mem1_reset_n" +set_location_assignment PIN_A39 -to "mem1_par" + +set_location_assignment PIN_H34 -to "mem1_a[0]" +set_location_assignment PIN_J34 -to "mem1_a[1]" +set_location_assignment PIN_G35 -to "mem1_a[2]" +set_location_assignment PIN_H35 -to "mem1_a[3]" +set_location_assignment PIN_L35 -to "mem1_a[4]" +set_location_assignment PIN_K35 -to "mem1_a[5]" +set_location_assignment PIN_L34 -to "mem1_a[6]" +set_location_assignment PIN_K34 -to "mem1_a[7]" +set_location_assignment PIN_N34 -to "mem1_a[8]" +set_location_assignment PIN_P34 -to "mem1_a[9]" +set_location_assignment PIN_M35 -to "mem1_a[10]" +set_location_assignment PIN_N35 -to "mem1_a[11]" +set_location_assignment PIN_B40 -to "mem1_a[12]" +set_location_assignment PIN_C39 -to "mem1_a[13]" +set_location_assignment PIN_D39 -to "mem1_a[14]" +set_location_assignment PIN_D38 -to "mem1_a[15]" +set_location_assignment PIN_C38 -to "mem1_a[16]" +set_location_assignment PIN_G37 -to "mem1_bg[0]" +set_location_assignment PIN_F34 -to "mem1_bg[1]" +set_location_assignment PIN_E35 -to "mem1_act_n" +set_location_assignment PIN_C36 -to "mem1_odt[0]" +set_location_assignment PIN_D36 -to "mem1_odt[1]" +set_location_assignment PIN_B37 -to "mem1_ck_p[0]" +set_location_assignment PIN_B38 -to "mem1_ck_n[0]" +set_location_assignment PIN_E36 -to "mem1_cs_n[0]" +set_location_assignment PIN_A38 -to "mem1_cs_n[1]" +set_location_assignment PIN_B36 -to "mem1_cke[0]" +set_location_assignment PIN_A37 -to "mem1_cke[1]" +set_location_assignment PIN_D37 -to "mem1_ba[0]" +set_location_assignment PIN_F37 -to "mem1_ba[1]" + +set_location_assignment PIN_K29 -to "mem1_dqs_p[0]" +set_location_assignment PIN_L29 -to "mem1_dqs_n[0]" +set_location_assignment PIN_R30 -to "mem1_dqs_p[1]" +set_location_assignment PIN_R29 -to "mem1_dqs_n[1]" +set_location_assignment PIN_E29 -to "mem1_dqs_p[2]" +set_location_assignment PIN_F29 -to "mem1_dqs_n[2]" +set_location_assignment PIN_G30 -to "mem1_dqs_p[3]" +set_location_assignment PIN_H30 -to "mem1_dqs_n[3]" +set_location_assignment PIN_M31 -to "mem1_dqs_p[4]" +set_location_assignment PIN_N31 -to "mem1_dqs_n[4]" +set_location_assignment PIN_P32 -to "mem1_dqs_p[5]" +set_location_assignment PIN_R32 -to "mem1_dqs_n[5]" +set_location_assignment PIN_G33 -to "mem1_dqs_p[6]" +set_location_assignment PIN_F33 -to "mem1_dqs_n[6]" +set_location_assignment PIN_K32 -to "mem1_dqs_p[7]" +set_location_assignment PIN_J32 -to "mem1_dqs_n[7]" +set_location_assignment PIN_D32 -to "mem1_dqs_p[8]" +set_location_assignment PIN_E32 -to "mem1_dqs_n[8]" +set_location_assignment PIN_G31 -to "mem1_dqs_p[9]" +set_location_assignment PIN_H31 -to "mem1_dqs_n[9]" +set_location_assignment PIN_B31 -to "mem1_dqs_p[10]" +set_location_assignment PIN_A32 -to "mem1_dqs_n[10]" +set_location_assignment PIN_A35 -to "mem1_dqs_p[11]" +set_location_assignment PIN_B35 -to "mem1_dqs_n[11]" +set_location_assignment PIN_E41 -to "mem1_dqs_p[12]" +set_location_assignment PIN_E40 -to "mem1_dqs_n[12]" +set_location_assignment PIN_C42 -to "mem1_dqs_p[13]" +set_location_assignment PIN_B42 -to "mem1_dqs_n[13]" +set_location_assignment PIN_H38 -to "mem1_dqs_p[14]" +set_location_assignment PIN_J38 -to "mem1_dqs_n[14]" +set_location_assignment PIN_H39 -to "mem1_dqs_p[15]" +set_location_assignment PIN_G38 -to "mem1_dqs_n[15]" +set_location_assignment PIN_E42 -to "mem1_dqs_p[16]" +set_location_assignment PIN_F42 -to "mem1_dqs_n[16]" +set_location_assignment PIN_L38 -to "mem1_dqs_p[17]" +set_location_assignment PIN_L39 -to "mem1_dqs_n[17]" + +set_location_assignment PIN_H29 -to "mem1_dq[0]" +set_location_assignment PIN_J29 -to "mem1_dq[1]" +set_location_assignment PIN_M30 -to "mem1_dq[2]" +set_location_assignment PIN_N30 -to "mem1_dq[3]" +set_location_assignment PIN_N29 -to "mem1_dq[4]" +set_location_assignment PIN_P29 -to "mem1_dq[5]" +set_location_assignment PIN_K30 -to "mem1_dq[6]" +set_location_assignment PIN_L30 -to "mem1_dq[7]" +set_location_assignment PIN_A28 -to "mem1_dq[8]" +set_location_assignment PIN_A29 -to "mem1_dq[9]" +set_location_assignment PIN_C28 -to "mem1_dq[10]" +set_location_assignment PIN_B28 -to "mem1_dq[11]" +set_location_assignment PIN_E30 -to "mem1_dq[12]" +set_location_assignment PIN_F30 -to "mem1_dq[13]" +set_location_assignment PIN_C29 -to "mem1_dq[14]" +set_location_assignment PIN_D29 -to "mem1_dq[15]" +set_location_assignment PIN_N33 -to "mem1_dq[16]" +set_location_assignment PIN_P33 -to "mem1_dq[17]" +set_location_assignment PIN_L33 -to "mem1_dq[18]" +set_location_assignment PIN_M33 -to "mem1_dq[19]" +set_location_assignment PIN_P31 -to "mem1_dq[20]" +set_location_assignment PIN_R31 -to "mem1_dq[21]" +set_location_assignment PIN_T33 -to "mem1_dq[22]" +set_location_assignment PIN_T32 -to "mem1_dq[23]" +set_location_assignment PIN_C34 -to "mem1_dq[24]" +set_location_assignment PIN_C35 -to "mem1_dq[25]" +set_location_assignment PIN_D34 -to "mem1_dq[26]" +set_location_assignment PIN_E34 -to "mem1_dq[27]" +set_location_assignment PIN_M32 -to "mem1_dq[28]" +set_location_assignment PIN_L32 -to "mem1_dq[29]" +set_location_assignment PIN_H33 -to "mem1_dq[30]" +set_location_assignment PIN_J33 -to "mem1_dq[31]" +set_location_assignment PIN_J31 -to "mem1_dq[32]" +set_location_assignment PIN_K31 -to "mem1_dq[33]" +set_location_assignment PIN_B33 -to "mem1_dq[34]" +set_location_assignment PIN_B32 -to "mem1_dq[35]" +set_location_assignment PIN_F32 -to "mem1_dq[36]" +set_location_assignment PIN_G32 -to "mem1_dq[37]" +set_location_assignment PIN_D33 -to "mem1_dq[38]" +set_location_assignment PIN_C33 -to "mem1_dq[39]" +set_location_assignment PIN_B30 -to "mem1_dq[40]" +set_location_assignment PIN_A30 -to "mem1_dq[41]" +set_location_assignment PIN_C30 -to "mem1_dq[42]" +set_location_assignment PIN_C31 -to "mem1_dq[43]" +set_location_assignment PIN_A33 -to "mem1_dq[44]" +set_location_assignment PIN_A34 -to "mem1_dq[45]" +set_location_assignment PIN_D31 -to "mem1_dq[46]" +set_location_assignment PIN_E31 -to "mem1_dq[47]" +set_location_assignment PIN_E39 -to "mem1_dq[48]" +set_location_assignment PIN_F40 -to "mem1_dq[49]" +set_location_assignment PIN_F38 -to "mem1_dq[50]" +set_location_assignment PIN_F39 -to "mem1_dq[51]" +set_location_assignment PIN_C41 -to "mem1_dq[52]" +set_location_assignment PIN_C40 -to "mem1_dq[53]" +set_location_assignment PIN_D42 -to "mem1_dq[54]" +set_location_assignment PIN_D41 -to "mem1_dq[55]" +set_location_assignment PIN_R37 -to "mem1_dq[56]" +set_location_assignment PIN_P37 -to "mem1_dq[57]" +set_location_assignment PIN_P38 -to "mem1_dq[58]" +set_location_assignment PIN_N38 -to "mem1_dq[59]" +set_location_assignment PIN_J37 -to "mem1_dq[60]" +set_location_assignment PIN_K37 -to "mem1_dq[61]" +set_location_assignment PIN_L37 -to "mem1_dq[62]" +set_location_assignment PIN_M37 -to "mem1_dq[63]" +set_location_assignment PIN_H41 -to "mem1_dq[64]" +set_location_assignment PIN_G41 -to "mem1_dq[65]" +set_location_assignment PIN_G42 -to "mem1_dq[66]" +set_location_assignment PIN_H42 -to "mem1_dq[67]" +set_location_assignment PIN_K39 -to "mem1_dq[68]" +set_location_assignment PIN_J39 -to "mem1_dq[69]" +set_location_assignment PIN_H40 -to "mem1_dq[70]" +set_location_assignment PIN_G40 -to "mem1_dq[71]" diff --git a/fpga/lib/pcie/example/520N_MX/fpga/fpga.sdc b/fpga/lib/pcie/example/520N_MX/fpga/fpga.sdc new file mode 100644 index 000000000..769df445b --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/fpga.sdc @@ -0,0 +1,89 @@ +# Timing constraints for BittWare 520N-MX + +set_time_format -unit ns -decimal_places 3 + +# Clock constraints +create_clock -name {config_clk} -period 20.000 [ get_ports {config_clk} ] +create_clock -name {usr_refclk0} -period 3.333 [ get_ports {usr_refclk0} ] +create_clock -name {usr_refclk1} -period 3.333 [ get_ports {usr_refclk1} ] + +create_clock -name {mem0_refclk} -period 3.333 [ get_ports {mem0_refclk} ] +create_clock -name {mem1_refclk} -period 3.333 [ get_ports {mem1_refclk} ] + +create_clock -name {esram_0_refclk} -period 5.000 [ get_ports {esram_0_refclk} ] +create_clock -name {esram_1_refclk} -period 5.000 [ get_ports {esram_1_refclk} ] + +create_clock -name {hbm_top_refclk} -period 5.000 [ get_ports {hbm_top_refclk} ] +create_clock -name {hbm_bottom_refclk} -period 5.000 [ get_ports {hbm_bottom_refclk} ] + +create_clock -name {pcie_refclk} -period 10.000 [ get_ports {pcie_refclk} ] + +create_clock -name {qsfp0_refclk} -period 1.551 [ get_ports {qsfp0_refclk} ] +create_clock -name {qsfp1_refclk} -period 1.551 [ get_ports {qsfp1_refclk} ] +create_clock -name {qsfp2_refclk} -period 1.551 [ get_ports {qsfp2_refclk} ] +create_clock -name {qsfp3_refclk} -period 1.551 [ get_ports {qsfp3_refclk} ] + +derive_clock_uncertainty + +set_clock_groups -asynchronous -group [ get_clocks {config_clk} ] +set_clock_groups -asynchronous -group [ get_clocks {usr_refclk0} ] +set_clock_groups -asynchronous -group [ get_clocks {usr_refclk1} ] + +set_clock_groups -asynchronous -group [ get_clocks {mem0_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {mem1_refclk} ] + +set_clock_groups -asynchronous -group [ get_clocks {esram_0_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {esram_1_refclk} ] + +set_clock_groups -asynchronous -group [ get_clocks {hbm_top_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {hbm_bottom_refclk} ] + +set_clock_groups -asynchronous -group [ get_clocks {pcie_refclk} ] + +set_clock_groups -asynchronous -group [ get_clocks {qsfp0_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {qsfp1_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {qsfp2_refclk} ] +set_clock_groups -asynchronous -group [ get_clocks {qsfp3_refclk} ] + +# JTAG constraints +create_clock -name {altera_reserved_tck} -period 62.500 {altera_reserved_tck} + +set_clock_groups -asynchronous -group {altera_reserved_tck} + +# IO constraints +set_false_path -to "led_user_red[*]" +set_false_path -to "led_user_grn[*]" +set_false_path -to "led_qsfp[*]" + +set_false_path -to "uart_rx" +set_false_path -from "uart_tx" + +set_false_path -to "fpga_i2c_sda" +set_false_path -from "fpga_i2c_sda" +set_false_path -to "fpga_i2c_scl" +set_false_path -from "fpga_i2c_scl" +set_false_path -to "fpga_i2c_req_l" +set_false_path -from "fpga_i2c_mux_gnt" + +set_false_path -from "fpga_gpio_1" +set_false_path -from "fpga_rst_n" + +set_false_path -from "pcie_perstn" + +set_false_path -from "qsfp_irq_n[*]" + +set_false_path -to "oc0_gpio[*]" +set_false_path -from "oc0_gpio[*]" +set_false_path -to "oc0_gpio_dir[*]" +set_false_path -to "oc0_buff_en_n[*]" + +set_false_path -to "oc1_gpio[*]" +set_false_path -from "oc1_gpio[*]" +set_false_path -to "oc1_gpio_dir[*]" +set_false_path -to "oc1_buff_en_n[*]" + +set_false_path -from "oc2_perst_n" +set_false_path -to "oc2_buff_in_sel" + +set_false_path -from "oc3_perst_n" +set_false_path -to "oc3_buff_in_sel" diff --git a/fpga/lib/pcie/example/520N_MX/fpga/fpga/Makefile b/fpga/lib/pcie/example/520N_MX/fpga/fpga/Makefile new file mode 100644 index 000000000..479d04f9a --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/fpga/Makefile @@ -0,0 +1,49 @@ + +# FPGA settings +FPGA_TOP = fpga +FPGA_FAMILY = "Stratix 10 MX" +FPGA_DEVICE = 1SM21CHU2F53E2VG + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/common/example_core_pcie_s10.v +SYN_FILES += rtl/common/example_core_pcie.v +SYN_FILES += rtl/common/example_core.v +SYN_FILES += rtl/common/axi_ram.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_rx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_tx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_cfg.v +SYN_FILES += lib/pcie/rtl/pcie_s10_msi.v +SYN_FILES += lib/pcie/rtl/pcie_axil_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v +SYN_FILES += lib/pcie/rtl/dma_psdpram.v +SYN_FILES += lib/pcie/rtl/arbiter.v +SYN_FILES += lib/pcie/rtl/priority_encoder.v +SYN_FILES += lib/pcie/rtl/pulse_merge.v + +# IP files +IP_TCL_FILES += ip/reset_release.tcl +IP_TCL_FILES += ip/pcie.tcl + +# QSF files +QSF_FILES = fpga.qsf + +# SDC files +SDC_FILES = fpga.sdc + +include ../common/quartus_pro.mk + +program: fpga + quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof@1" diff --git a/fpga/lib/pcie/example/520N_MX/fpga/ip/pcie.tcl b/fpga/lib/pcie/example/520N_MX/fpga/ip/pcie.tcl new file mode 100644 index 000000000..41addc1aa --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/ip/pcie.tcl @@ -0,0 +1,350 @@ +package require -exact qsys 21.3 + +# create the system "pcie" +proc do_create_pcie {} { + # create the system + create_system pcie + set_project_property DEVICE {1SM21CHU2F53E2VG} + set_project_property DEVICE_FAMILY {Stratix 10} + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance pcie_s10_hip_ast_0 altera_pcie_s10_hip_ast + set_instance_parameter_value pcie_s10_hip_ast_0 {anlg_voltage} {1_1V} + set_instance_parameter_value pcie_s10_hip_ast_0 {apps_type_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_clk_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_control_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_npor_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_pipe_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {ceb_extend_pcie_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {chosen_devkit_hwtcl} {Stratix 10 MX H-Tile Production FPGA Development Kit} + set_instance_parameter_value pcie_s10_hip_ast_0 {cvp_user_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {design_environment} {NATIVE} + set_instance_parameter_value pcie_s10_hip_ast_0 {device_ctrl_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {disable_256_to_512_adapter_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {eios_workaround_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_avst_reset_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_qii_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_sim_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_sim_rp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_synth_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_synth_rp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_tb_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_multi_func_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pcie_cv_fix} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pipe32_phyip_ser_driver_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pld_warm_rst_rdy_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_rx_buffer_limit_ports_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_sriov_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_test_out_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {hip_reconfig_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {hrc_rstctl_timer_g_delay_added_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {msi_info_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pcie_link_inspector_avmm_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pcie_link_inspector_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_auto_lane_flip_ctrl_en_hwtcl} {enable} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar0_address_width_hwtcl} {24} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar0_type_hwtcl} {64-bit prefetchable memory} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar2_address_width_hwtcl} {24} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar2_type_hwtcl} {64-bit prefetchable memory} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_eq_eieos_cnt_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_loopback_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msi_multiple_msg_cap_hwtcl} {32} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_type0_device_id_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_type0_vendor_id_hwtcl} {4660} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ep_l0s_accpt_latency_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ep_l1_accpt_latency_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ext_tag_supp_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_flr_cap_user_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_phy_slot_num_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_port_num_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_sel_deemphasis_hwtcl} {6dB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_clk_config_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_power_limit_scale_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_power_limit_value_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_slot_imp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_revision_id_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_subsys_dev_id_hwtcl} {1313} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_subsys_vendor_id_hwtcl} {6538} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pll_refclk_freq_hwtcl} {100 MHz} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_design_example_hwtcl} {PIO} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_design_example_rtl_lang_hwtcl} {Verilog} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_example_design_sim_BFM_hwtcl} {Intel FPGA BFM} + set_instance_parameter_value pcie_s10_hip_ast_0 {serial_sim_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {targeted_devkit_hwtcl} {NONE} + set_instance_parameter_value pcie_s10_hip_ast_0 {total_pf_count_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_ast_parity_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_pll_lock_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_rpbfm_pro} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_ep_native_hwtcl} {Native} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_maxpayload_size_hwtcl} {1024} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_msi_enable_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_rp_ep_mode_hwtcl} {Native Endpoint} + set_instance_parameter_value pcie_s10_hip_ast_0 {wrala_hwtcl} {Gen3x8, Interface - 256 bit, 250 MHz} + set_instance_parameter_value pcie_s10_hip_ast_0 {xcvr_adme_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {xcvr_reconfig_hwtcl} {0} + set_instance_property pcie_s10_hip_ast_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property refclk EXPORT_OF pcie_s10_hip_ast_0.refclk + set_interface_property coreclkout_hip EXPORT_OF pcie_s10_hip_ast_0.coreclkout_hip + set_interface_property npor EXPORT_OF pcie_s10_hip_ast_0.npor + set_interface_property hip_rst EXPORT_OF pcie_s10_hip_ast_0.hip_rst + set_interface_property clr_st EXPORT_OF pcie_s10_hip_ast_0.clr_st + set_interface_property ninit_done EXPORT_OF pcie_s10_hip_ast_0.ninit_done + set_interface_property rx_st EXPORT_OF pcie_s10_hip_ast_0.rx_st + set_interface_property tx_st EXPORT_OF pcie_s10_hip_ast_0.tx_st + set_interface_property rx_bar EXPORT_OF pcie_s10_hip_ast_0.rx_bar + set_interface_property tx_cred EXPORT_OF pcie_s10_hip_ast_0.tx_cred + set_interface_property int_msi EXPORT_OF pcie_s10_hip_ast_0.int_msi + set_interface_property hip_status EXPORT_OF pcie_s10_hip_ast_0.hip_status + set_interface_property config_tl EXPORT_OF pcie_s10_hip_ast_0.config_tl + set_interface_property hip_ctrl EXPORT_OF pcie_s10_hip_ast_0.hip_ctrl + set_interface_property currentspeed EXPORT_OF pcie_s10_hip_ast_0.currentspeed + set_interface_property hip_pipe EXPORT_OF pcie_s10_hip_ast_0.hip_pipe + set_interface_property hip_serial EXPORT_OF pcie_s10_hip_ast_0.hip_serial + set_interface_property power_mgnt EXPORT_OF pcie_s10_hip_ast_0.power_mgnt + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {pcie.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {pcie} + + # save the system + sync_sysinfo_parameters + save_system pcie +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_pcie + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/fpga/lib/pcie/example/520N_MX/fpga/ip/reset_release.tcl b/fpga/lib/pcie/example/520N_MX/fpga/ip/reset_release.tcl new file mode 100644 index 000000000..b79c1ae73 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/ip/reset_release.tcl @@ -0,0 +1,50 @@ +package require -exact qsys 20.4 + +# create the system "reset_release" +proc do_create_reset_release {} { + # create the system + create_system reset_release + set_project_property DEVICE {1SM21CHU2F53E2VG} + set_project_property DEVICE_FAMILY {Stratix 10} + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance s10_user_rst_clkgate_0 altera_s10_user_rst_clkgate + set_instance_parameter_value s10_user_rst_clkgate_0 {outputType} {Conduit Interface} + set_instance_property s10_user_rst_clkgate_0 AUTO_EXPORT true + + # add wirelevel expressions + + # add the exports + set_interface_property ninit_done EXPORT_OF s10_user_rst_clkgate_0.ninit_done + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {reset_release.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {reset_release} + + # save the system + sync_sysinfo_parameters + save_system reset_release +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_reset_release + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/fpga/lib/pcie/example/520N_MX/fpga/lib/pcie b/fpga/lib/pcie/example/520N_MX/fpga/lib/pcie new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/lib/pcie @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/common b/fpga/lib/pcie/example/520N_MX/fpga/rtl/common new file mode 120000 index 000000000..543afe472 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/common @@ -0,0 +1 @@ +../lib/pcie/example/common/rtl/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/debounce_switch.v b/fpga/lib/pcie/example/520N_MX/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..8e93a50c4 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/debounce_switch.v @@ -0,0 +1,93 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga.v b/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga.v new file mode 100644 index 000000000..4fcbdcd92 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga.v @@ -0,0 +1,533 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 300 MHz + */ + input wire usr_refclk0, + + /* + * GPIO + */ + output wire [1:0] led_user_grn, + output wire [1:0] led_user_red, + output wire [3:0] led_qsfp, + + /* + * PCIe: gen 3 x16 + */ + output wire [7:0] pcie_tx, + input wire [7:0] pcie_rx, + input wire pcie_refclk, + input wire pcie_perstn +); + +parameter SEG_COUNT = 1; +parameter SEG_DATA_WIDTH = 256; +parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32); + +parameter TX_SEQ_NUM_WIDTH = 6; + +parameter PCIE_TAG_COUNT = 256; +parameter BAR0_APERTURE = 24; +parameter BAR2_APERTURE = 24; + +// Clock and reset + +wire ninit_done; + +reset_release reset_release_inst ( + .ninit_done (ninit_done) +); + +wire clk_100mhz = usr_refclk0; +wire rst_100mhz; + +sync_reset #( + .N(20) +) +sync_reset_100mhz_inst ( + .clk(clk_100mhz), + .rst(ninit_done), + .out(rst_100mhz) +); + +wire coreclkout_hip; +wire reset_status; + +wire clk = coreclkout_hip; +wire rst = reset_status; + +wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data; +wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty; +wire [SEG_COUNT-1:0] rx_st_sop; +wire [SEG_COUNT-1:0] rx_st_eop; +wire [SEG_COUNT-1:0] rx_st_valid; +wire rx_st_ready; +wire [SEG_COUNT-1:0] rx_st_vf_active = 0; +wire [SEG_COUNT*3-1:0] rx_st_func_num = 0; +wire [SEG_COUNT*11-1:0] rx_st_vf_num = 0; +wire [SEG_COUNT*3-1:0] rx_st_bar_range; + +wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data; +wire [SEG_COUNT-1:0] tx_st_sop; +wire [SEG_COUNT-1:0] tx_st_eop; +wire [SEG_COUNT-1:0] tx_st_valid; +wire tx_st_ready; +wire [SEG_COUNT-1:0] tx_st_err; + +wire [7:0] tx_ph_cdts; +wire [11:0] tx_pd_cdts; +wire [7:0] tx_nph_cdts; +wire [11:0] tx_npd_cdts; +wire [7:0] tx_cplh_cdts; +wire [11:0] tx_cpld_cdts; +wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed; +wire [SEG_COUNT-1:0] tx_data_cdts_consumed; +wire [SEG_COUNT*2-1:0] tx_cdts_type; +wire [SEG_COUNT*1-1:0] tx_cdts_data_value; + +wire app_msi_req; +wire app_msi_ack; +wire [2:0] app_msi_tc; +wire [4:0] app_msi_num; +wire [1:0] app_msi_func_num; + +wire [31:0] tl_cfg_ctl; +wire [4:0] tl_cfg_add; +wire [1:0] tl_cfg_func; + +pcie pcie_hip_inst ( + .refclk (pcie_refclk), + .coreclkout_hip (coreclkout_hip), + .npor (!rst_100mhz), + .pin_perst (pcie_perstn), + .reset_status (reset_status), + .serdes_pll_locked (), + .pld_core_ready (1'b1), + .pld_clk_inuse (), + .testin_zero (), + .clr_st (), + .ninit_done (ninit_done), + .rx_st_ready (rx_st_ready), + .rx_st_sop (rx_st_sop), + .rx_st_eop (rx_st_eop), + .rx_st_data (rx_st_data), + .rx_st_valid (rx_st_valid), + .rx_st_empty (rx_st_empty), + .tx_st_sop (tx_st_sop), + .tx_st_eop (tx_st_eop), + .tx_st_data (tx_st_data), + .tx_st_valid (tx_st_valid), + .tx_st_err (tx_st_err), + .tx_st_ready (tx_st_ready), + .rx_st_bar_range (rx_st_bar_range), + .tx_cdts_type (tx_cdts_type), + .tx_data_cdts_consumed (tx_data_cdts_consumed), + .tx_hdr_cdts_consumed (tx_hdr_cdts_consumed), + .tx_cdts_data_value (tx_cdts_data_value), + .tx_cpld_cdts (tx_cpld_cdts), + .tx_pd_cdts (tx_pd_cdts), + .tx_npd_cdts (tx_npd_cdts), + .tx_cplh_cdts (tx_cplh_cdts), + .tx_ph_cdts (tx_ph_cdts), + .tx_nph_cdts (tx_nph_cdts), + .app_msi_req (app_msi_req), + .app_msi_ack (app_msi_ack), + .app_msi_tc (app_msi_tc), + .app_msi_num (app_msi_num), + .app_int_sts (4'd0), + .app_msi_func_num (app_msi_func_num), + .int_status (), + .int_status_common (), + .derr_cor_ext_rpl (), + .derr_rpl (), + .derr_cor_ext_rcv (), + .derr_uncor_ext_rcv (), + .rx_par_err (), + .tx_par_err (), + .ltssmstate (), + .link_up (), + .lane_act (), + .tl_cfg_func (tl_cfg_func), + .tl_cfg_add (tl_cfg_add), + .tl_cfg_ctl (tl_cfg_ctl), + .app_err_valid (0), + .app_err_hdr (0), + .app_err_info (0), + .app_err_func_num (0), + .test_in (0), + .simu_mode_pipe (0), + .currentspeed (), + .sim_pipe_pclk_in (1'b0), + .sim_pipe_rate (), + .sim_ltssmstate (), + .txdata0 (), + .txdata1 (), + .txdata2 (), + .txdata3 (), + .txdata4 (), + .txdata5 (), + .txdata6 (), + .txdata7 (), + .txdatak0 (), + .txdatak1 (), + .txdatak2 (), + .txdatak3 (), + .txdatak4 (), + .txdatak5 (), + .txdatak6 (), + .txdatak7 (), + .txcompl0 (), + .txcompl1 (), + .txcompl2 (), + .txcompl3 (), + .txcompl4 (), + .txcompl5 (), + .txcompl6 (), + .txcompl7 (), + .txelecidle0 (), + .txelecidle1 (), + .txelecidle2 (), + .txelecidle3 (), + .txelecidle4 (), + .txelecidle5 (), + .txelecidle6 (), + .txelecidle7 (), + .txdetectrx0 (), + .txdetectrx1 (), + .txdetectrx2 (), + .txdetectrx3 (), + .txdetectrx4 (), + .txdetectrx5 (), + .txdetectrx6 (), + .txdetectrx7 (), + .powerdown0 (), + .powerdown1 (), + .powerdown2 (), + .powerdown3 (), + .powerdown4 (), + .powerdown5 (), + .powerdown6 (), + .powerdown7 (), + .txmargin0 (), + .txmargin1 (), + .txmargin2 (), + .txmargin3 (), + .txmargin4 (), + .txmargin5 (), + .txmargin6 (), + .txmargin7 (), + .txdeemph0 (), + .txdeemph1 (), + .txdeemph2 (), + .txdeemph3 (), + .txdeemph4 (), + .txdeemph5 (), + .txdeemph6 (), + .txdeemph7 (), + .txswing0 (), + .txswing1 (), + .txswing2 (), + .txswing3 (), + .txswing4 (), + .txswing5 (), + .txswing6 (), + .txswing7 (), + .txsynchd0 (), + .txsynchd1 (), + .txsynchd2 (), + .txsynchd3 (), + .txsynchd4 (), + .txsynchd5 (), + .txsynchd6 (), + .txsynchd7 (), + .txblkst0 (), + .txblkst1 (), + .txblkst2 (), + .txblkst3 (), + .txblkst4 (), + .txblkst5 (), + .txblkst6 (), + .txblkst7 (), + .txdataskip0 (), + .txdataskip1 (), + .txdataskip2 (), + .txdataskip3 (), + .txdataskip4 (), + .txdataskip5 (), + .txdataskip6 (), + .txdataskip7 (), + .rate0 (), + .rate1 (), + .rate2 (), + .rate3 (), + .rate4 (), + .rate5 (), + .rate6 (), + .rate7 (), + .rxpolarity0 (), + .rxpolarity1 (), + .rxpolarity2 (), + .rxpolarity3 (), + .rxpolarity4 (), + .rxpolarity5 (), + .rxpolarity6 (), + .rxpolarity7 (), + .currentrxpreset0 (), + .currentrxpreset1 (), + .currentrxpreset2 (), + .currentrxpreset3 (), + .currentrxpreset4 (), + .currentrxpreset5 (), + .currentrxpreset6 (), + .currentrxpreset7 (), + .currentcoeff0 (), + .currentcoeff1 (), + .currentcoeff2 (), + .currentcoeff3 (), + .currentcoeff4 (), + .currentcoeff5 (), + .currentcoeff6 (), + .currentcoeff7 (), + .rxeqeval0 (), + .rxeqeval1 (), + .rxeqeval2 (), + .rxeqeval3 (), + .rxeqeval4 (), + .rxeqeval5 (), + .rxeqeval6 (), + .rxeqeval7 (), + .rxeqinprogress0 (), + .rxeqinprogress1 (), + .rxeqinprogress2 (), + .rxeqinprogress3 (), + .rxeqinprogress4 (), + .rxeqinprogress5 (), + .rxeqinprogress6 (), + .rxeqinprogress7 (), + .invalidreq0 (), + .invalidreq1 (), + .invalidreq2 (), + .invalidreq3 (), + .invalidreq4 (), + .invalidreq5 (), + .invalidreq6 (), + .invalidreq7 (), + .rxdata0 (32'd0), + .rxdata1 (32'd0), + .rxdata2 (32'd0), + .rxdata3 (32'd0), + .rxdata4 (32'd0), + .rxdata5 (32'd0), + .rxdata6 (32'd0), + .rxdata7 (32'd0), + .rxdatak0 (4'd0), + .rxdatak1 (4'd0), + .rxdatak2 (4'd0), + .rxdatak3 (4'd0), + .rxdatak4 (4'd0), + .rxdatak5 (4'd0), + .rxdatak6 (4'd0), + .rxdatak7 (4'd0), + .phystatus0 (1'b0), + .phystatus1 (1'b0), + .phystatus2 (1'b0), + .phystatus3 (1'b0), + .phystatus4 (1'b0), + .phystatus5 (1'b0), + .phystatus6 (1'b0), + .phystatus7 (1'b0), + .rxvalid0 (1'b0), + .rxvalid1 (1'b0), + .rxvalid2 (1'b0), + .rxvalid3 (1'b0), + .rxvalid4 (1'b0), + .rxvalid5 (1'b0), + .rxvalid6 (1'b0), + .rxvalid7 (1'b0), + .rxstatus0 (3'd0), + .rxstatus1 (3'd0), + .rxstatus2 (3'd0), + .rxstatus3 (3'd0), + .rxstatus4 (3'd0), + .rxstatus5 (3'd0), + .rxstatus6 (3'd0), + .rxstatus7 (3'd0), + .rxelecidle0 (1'b0), + .rxelecidle1 (1'b0), + .rxelecidle2 (1'b0), + .rxelecidle3 (1'b0), + .rxelecidle4 (1'b0), + .rxelecidle5 (1'b0), + .rxelecidle6 (1'b0), + .rxelecidle7 (1'b0), + .rxsynchd0 (2'd0), + .rxsynchd1 (2'd0), + .rxsynchd2 (2'd0), + .rxsynchd3 (2'd0), + .rxsynchd4 (2'd0), + .rxsynchd5 (2'd0), + .rxsynchd6 (2'd0), + .rxsynchd7 (2'd0), + .rxblkst0 (1'b0), + .rxblkst1 (1'b0), + .rxblkst2 (1'b0), + .rxblkst3 (1'b0), + .rxblkst4 (1'b0), + .rxblkst5 (1'b0), + .rxblkst6 (1'b0), + .rxblkst7 (1'b0), + .rxdataskip0 (1'b0), + .rxdataskip1 (1'b0), + .rxdataskip2 (1'b0), + .rxdataskip3 (1'b0), + .rxdataskip4 (1'b0), + .rxdataskip5 (1'b0), + .rxdataskip6 (1'b0), + .rxdataskip7 (1'b0), + .dirfeedback0 (6'd0), + .dirfeedback1 (6'd0), + .dirfeedback2 (6'd0), + .dirfeedback3 (6'd0), + .dirfeedback4 (6'd0), + .dirfeedback5 (6'd0), + .dirfeedback6 (6'd0), + .dirfeedback7 (6'd0), + .sim_pipe_mask_tx_pll_lock (1'b0), + .rx_in0 (pcie_rx[0]), + .rx_in1 (pcie_rx[1]), + .rx_in2 (pcie_rx[2]), + .rx_in3 (pcie_rx[3]), + .rx_in4 (pcie_rx[4]), + .rx_in5 (pcie_rx[5]), + .rx_in6 (pcie_rx[6]), + .rx_in7 (pcie_rx[7]), + .tx_out0 (pcie_tx[0]), + .tx_out1 (pcie_tx[1]), + .tx_out2 (pcie_tx[2]), + .tx_out3 (pcie_tx[3]), + .tx_out4 (pcie_tx[4]), + .tx_out5 (pcie_tx[5]), + .tx_out6 (pcie_tx[6]), + .tx_out7 (pcie_tx[7]), + .pm_linkst_in_l1 (), + .pm_linkst_in_l0s (), + .pm_state (), + .pm_dstate (), + .apps_pm_xmt_pme (0), + .apps_ready_entr_l23 (0), + .apps_pm_xmt_turnoff (0), + .app_init_rst (0), + .app_xfer_pending (0) +); + +fpga_core #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +fpga_core_inst ( + .clk(clk), + .rst(rst), + + /* + * GPIO + */ + .led_user_grn(led_user_grn), + .led_user_red(led_user_red), + .led_qsfp(led_qsfp), + + /* + * H-tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + /* + * H-tile TX AVST interface + */ + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + /* + * H-tile TX flow control + */ + .tx_ph_cdts(tx_ph_cdts), + .tx_pd_cdts(tx_pd_cdts), + .tx_nph_cdts(tx_nph_cdts), + .tx_npd_cdts(tx_npd_cdts), + .tx_cplh_cdts(tx_cplh_cdts), + .tx_cpld_cdts(tx_cpld_cdts), + .tx_hdr_cdts_consumed(tx_hdr_cdts_consumed), + .tx_data_cdts_consumed(tx_data_cdts_consumed), + .tx_cdts_type(tx_cdts_type), + .tx_cdts_data_value(tx_cdts_data_value), + + /* + * H-tile MSI interrupt interface + */ + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + /* + * H-tile configuration interface + */ + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga_core.v b/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..567a6aa5f --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/fpga_core.v @@ -0,0 +1,180 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter SEG_COUNT = 1, + parameter SEG_DATA_WIDTH = 256, + parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32), + parameter TX_SEQ_NUM_WIDTH = 6, + parameter PCIE_TAG_COUNT = 256, + parameter BAR0_APERTURE = 24, + parameter BAR2_APERTURE = 24 +) +( + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [1:0] led_user_grn, + output wire [1:0] led_user_red, + output wire [3:0] led_qsfp, + + /* + * H-Tile interface + */ + input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data, + input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty, + input wire [SEG_COUNT-1:0] rx_st_sop, + input wire [SEG_COUNT-1:0] rx_st_eop, + input wire [SEG_COUNT-1:0] rx_st_valid, + output wire rx_st_ready, + input wire [SEG_COUNT-1:0] rx_st_vf_active, + input wire [SEG_COUNT*2-1:0] rx_st_func_num, + input wire [SEG_COUNT*11-1:0] rx_st_vf_num, + input wire [SEG_COUNT*3-1:0] rx_st_bar_range, + + output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data, + output wire [SEG_COUNT-1:0] tx_st_sop, + output wire [SEG_COUNT-1:0] tx_st_eop, + output wire [SEG_COUNT-1:0] tx_st_valid, + input wire tx_st_ready, + output wire [SEG_COUNT-1:0] tx_st_err, + + input wire [7:0] tx_ph_cdts, + input wire [11:0] tx_pd_cdts, + input wire [7:0] tx_nph_cdts, + input wire [11:0] tx_npd_cdts, + input wire [7:0] tx_cplh_cdts, + input wire [11:0] tx_cpld_cdts, + input wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed, + input wire [SEG_COUNT-1:0] tx_data_cdts_consumed, + input wire [SEG_COUNT*2-1:0] tx_cdts_type, + input wire [SEG_COUNT*1-1:0] tx_cdts_data_value, + + output wire app_msi_req, + input wire app_msi_ack, + output wire [2:0] app_msi_tc, + output wire [4:0] app_msi_num, + output wire [1:0] app_msi_func_num, + + input wire [31:0] tl_cfg_ctl, + input wire [4:0] tl_cfg_add, + input wire [1:0] tl_cfg_func +); + +assign led_user_grn = 0; +assign led_user_red = 0; +assign led_qsfp = 0; + +example_core_pcie_s10 #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .TX_SEQ_NUM_ENABLE(1), + .L_TILE(0), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(PCIE_TAG_COUNT), + .READ_TX_LIMIT(2**TX_SEQ_NUM_WIDTH), + .READ_TX_FC_ENABLE(1), + .WRITE_OP_TABLE_SIZE(2**TX_SEQ_NUM_WIDTH), + .WRITE_TX_LIMIT(2**TX_SEQ_NUM_WIDTH), + .WRITE_TX_FC_ENABLE(1), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +example_core_pcie_s10_inst ( + .clk(clk), + .rst(rst), + + /* + * H-tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + /* + * H-tile TX AVST interface + */ + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + /* + * H-tile TX flow control + */ + .tx_ph_cdts(tx_ph_cdts), + .tx_pd_cdts(tx_pd_cdts), + .tx_nph_cdts(tx_nph_cdts), + .tx_npd_cdts(tx_npd_cdts), + .tx_cplh_cdts(tx_cplh_cdts), + .tx_cpld_cdts(tx_cpld_cdts), + .tx_hdr_cdts_consumed(tx_hdr_cdts_consumed), + .tx_data_cdts_consumed(tx_data_cdts_consumed), + .tx_cdts_type(tx_cdts_type), + .tx_cdts_data_value(tx_cdts_data_value), + + /* + * H-tile MSI interrupt interface + */ + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + /* + * H-tile configuration interface + */ + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_reset.v b/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..8c2dd529c --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_reset.v @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2014-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. + +*/ + +// Language: Verilog-2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset # +( + // depth of synchronizer + parameter N = 2 +) +( + input wire clk, + input wire rst, + output wire out +); + +(* srl_style = "register" *) +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) begin + sync_reg <= {N{1'b1}}; + end else begin + sync_reg <= {sync_reg[N-2:0], 1'b0}; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_signal.v b/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/rtl/sync_signal.v @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/Makefile b/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..49474b6ee --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/Makefile @@ -0,0 +1,109 @@ +# 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 += ../../rtl/common/example_core_pcie_s10.v +VERILOG_SOURCES += ../../rtl/common/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/common/example_core.v +VERILOG_SOURCES += ../../rtl/common/axi_ram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if_rx.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if_tx.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_SEG_COUNT ?= 1 +export PARAM_SEG_DATA_WIDTH ?= 256 +export PARAM_SEG_EMPTY_WIDTH ?= $(shell python -c "print((($(PARAM_SEG_DATA_WIDTH)//32)-1).bit_length())" ) +export PARAM_TX_SEQ_NUM_WIDTH ?= 6 +export PARAM_PCIE_TAG_COUNT ?= 64 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).SEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GSEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -GSEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -GSEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/test_fpga_core.py b/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..d74ff2252 --- /dev/null +++ b/fpga/lib/pcie/example/520N_MX/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,306 @@ +""" + +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 + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = S10PcieDevice( + # configuration options + pcie_generation=3, + # pcie_link_width=8, + # pld_clk_frequency=250e6, + l_tile=False, + + # signals + # Clock and reset + # npor=dut.npor, + # pin_perst=dut.pin_perst, + # ninit_done=dut.ninit_done, + # pld_clk_inuse=dut.pld_clk_inuse, + # pld_core_ready=dut.pld_core_ready, + reset_status=dut.rst, + # clr_st=dut.clr_st, + # refclk=dut.refclk, + coreclkout_hip=dut.clk, + + # RX interface + rx_bus=S10RxBus.from_prefix(dut, "rx_st"), + + # TX interface + tx_bus=S10TxBus.from_prefix(dut, "tx_st"), + + # TX flow control + tx_ph_cdts=dut.tx_ph_cdts, + tx_pd_cdts=dut.tx_pd_cdts, + tx_nph_cdts=dut.tx_nph_cdts, + tx_npd_cdts=dut.tx_npd_cdts, + tx_cplh_cdts=dut.tx_cplh_cdts, + tx_cpld_cdts=dut.tx_cpld_cdts, + tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, + tx_data_cdts_consumed=dut.tx_data_cdts_consumed, + tx_cdts_type=dut.tx_cdts_type, + tx_cdts_data_value=dut.tx_cdts_data_value, + + # Hard IP status + # int_status=dut.int_status, + # int_status_common=dut.int_status_common, + # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, + # derr_rpl=dut.derr_rpl, + # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, + # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, + # rx_par_err=dut.rx_par_err, + # tx_par_err=dut.tx_par_err, + # ltssmstate=dut.ltssmstate, + # link_up=dut.link_up, + # lane_act=dut.lane_act, + # currentspeed=dut.currentspeed, + + # Power management + # pm_linkst_in_l1=dut.pm_linkst_in_l1, + # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, + # pm_state=dut.pm_state, + # pm_dstate=dut.pm_dstate, + # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, + # apps_ready_entr_l23=dut.apps_ready_entr_l23, + # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, + # app_init_rst=dut.app_init_rst, + # app_xfer_pending=dut.app_xfer_pending, + + # Interrupt interface + app_msi_req=dut.app_msi_req, + app_msi_ack=dut.app_msi_ack, + app_msi_tc=dut.app_msi_tc, + app_msi_num=dut.app_msi_num, + app_msi_func_num=dut.app_msi_func_num, + # app_int_sts=dut.app_int_sts, + + # Error interface + # app_err_valid=dut.app_err_valid, + # app_err_hdr=dut.app_err_hdr, + # app_err_info=dut.app_err_info, + # app_err_func_num=dut.app_err_func_num, + + # Configuration output + tl_cfg_func=dut.tl_cfg_func, + tl_cfg_add=dut.tl_cfg_add, + tl_cfg_ctl=dut.tl_cfg_ctl, + + # Configuration extension bus + # ceb_req=dut.ceb_req, + # ceb_ack=dut.ceb_ack, + # ceb_addr=dut.ceb_addr, + # ceb_din=dut.ceb_din, + # ceb_dout=dut.ceb_dout, + # ceb_wr=dut.ceb_wr, + # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, + # ceb_func_num=dut.ceb_func_num, + # ceb_vf_num=dut.ceb_vf_num, + # ceb_vf_active=dut.ceb_vf_active, + + # Hard IP reconfiguration interface + # hip_reconfig_clk=dut.hip_reconfig_clk, + # hip_reconfig_address=dut.hip_reconfig_address, + # hip_reconfig_read=dut.hip_reconfig_read, + # hip_reconfig_readdata=dut.hip_reconfig_readdata, + # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, + # hip_reconfig_write=dut.hip_reconfig_write, + # hip_reconfig_writedata=dut.hip_reconfig_writedata, + # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(2, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + + # enable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 3) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "example_core_pcie_s10.v"), + os.path.join(rtl_dir, "common", "example_core_pcie.v"), + os.path.join(rtl_dir, "common", "example_core.v"), + os.path.join(rtl_dir, "common", "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_rx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_tx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['SEG_COUNT'] = 1 + parameters['SEG_DATA_WIDTH'] = 256 + parameters['SEG_EMPTY_WIDTH'] = (parameters['SEG_DATA_WIDTH'] // 32 - 1).bit_length() + parameters['TX_SEQ_NUM_WIDTH'] = 6 + parameters['PCIE_TAG_COUNT'] = 64 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/ADM_PCIE_9V3/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/ADM_PCIE_9V3/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..01d44aa32 100644 --- a/fpga/lib/pcie/example/ADM_PCIE_9V3/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/ADM_PCIE_9V3/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {9003} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/AU200/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/AU200/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..3496725d4 100644 --- a/fpga/lib/pcie/example/AU200/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/AU200/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {90c8} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..d5a908b6e 100644 --- a/fpga/lib/pcie/example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {90fa} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/AU280/fpga_axi/ip/pcie4c_uscale_plus_0.tcl b/fpga/lib/pcie/example/AU280/fpga_axi/ip/pcie4c_uscale_plus_0.tcl index 13b91730e..36fbed63b 100644 --- a/fpga/lib/pcie/example/AU280/fpga_axi/ip/pcie4c_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/AU280/fpga_axi/ip/pcie4c_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {9118} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/AU50/fpga_axi/ip/pcie4c_uscale_plus_0.tcl b/fpga/lib/pcie/example/AU50/fpga_axi/ip/pcie4c_uscale_plus_0.tcl index 13b91730e..fba62239f 100644 --- a/fpga/lib/pcie/example/AU50/fpga_axi/ip/pcie4c_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/AU50/fpga_axi/ip/pcie4c_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {9032} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/README.md b/fpga/lib/pcie/example/ExaNIC_X10/fpga/README.md new file mode 100644 index 000000000..d6597ec86 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/README.md @@ -0,0 +1,19 @@ +# Verilog PCIe ExaNIC X10 Example Design + +## Introduction + +This example design targets the Exablaze ExaNIC X10 FPGA board. + +The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design. + +* FPGA: xcku035-fbva676-2-c + +## How to build + +Run `make` to build. Ensure that the Xilinx Vivado toolchain components are in PATH. + +Run `make` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled. + +## How to test + +Run `make program` to program the ExaNIC X10 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output. diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/common/vivado.mk b/fpga/lib/pcie/example/ExaNIC_X10/fpga/common/vivado.mk new file mode 100644 index 000000000..d47a43947 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/common/vivado.mk @@ -0,0 +1,126 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: fpga vivado tmpclean clean distclean + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(SYN_FILES))) $(filter /% ./%,$(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(INC_FILES))) $(filter /% ./%,$(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XCI_FILES))) $(filter /% ./%,$(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(IP_TCL_FILES))) $(filter /% ./%,$(IP_TCL_FILES)) +CONFIG_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(CONFIG_TCL_FILES))) $(filter /% ./%,$(CONFIG_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XDC_FILES))) $(filter /% ./%,$(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean:: + -rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean:: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean:: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $(FPGA_TOP)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done + +update_config.tcl: $(CONFIG_TCL_FILES_REL) + echo "open_project -quiet $(FPGA_TOP).xpr" > $@ + for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(FPGA_TOP).xpr: create_project.tcl update_config.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) $(CONFIG_TCL_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/driver b/fpga/lib/pcie/example/ExaNIC_X10/fpga/driver new file mode 120000 index 000000000..4a54c76b5 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/driver @@ -0,0 +1 @@ +../../common/driver/example/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga.xdc b/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga.xdc new file mode 100644 index 000000000..ccd6a97e3 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga.xdc @@ -0,0 +1,183 @@ +# XDC constraints for the ExaNIC X10 +# part: xcku035-fbva676-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design] +set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type2 [current_design] +set_property CONFIG_MODE BPI16 [current_design] + +# 100 MHz system clock +#set_property -dict {LOC D18 IOSTANDARD LVDS} [get_ports clk_100mhz_p] +#set_property -dict {LOC C18 IOSTANDARD LVDS} [get_ports clk_100mhz_n] +#create_clock -period 10 -name clk_100mhz [get_ports clk_100mhz_p] + +# LEDs +set_property -dict {LOC A25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[0]}] +set_property -dict {LOC A24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[1]}] +set_property -dict {LOC E23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[0]}] +set_property -dict {LOC D26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[1]}] +set_property -dict {LOC C23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[0]}] +set_property -dict {LOC D23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[1]}] + +set_false_path -to [get_ports {sfp_1_led[*] sfp_2_led[*] sma_led[*]}] +set_output_delay 0 [get_ports {sfp_1_led[*] sfp_2_led[*] sma_led[*]}] + +# GPIO +#set_property -dict {LOC W26 IOSTANDARD LVCMOS18} [get_ports gpio[0]] +#set_property -dict {LOC Y26 IOSTANDARD LVCMOS18} [get_ports gpio[1]] +#set_property -dict {LOC AB26 IOSTANDARD LVCMOS18} [get_ports gpio[2]] +#set_property -dict {LOC AC26 IOSTANDARD LVCMOS18} [get_ports gpio[3]] + +# SMA +#set_property -dict {LOC B17 IOSTANDARD LVCMOS18} [get_ports sma_in] +#set_property -dict {LOC B16 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports sma_out] +#set_property -dict {LOC B19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sma_out_en] +#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sma_term_en] + +#set_false_path -to [get_ports {sma_out sma_term sma_term_en}] +#set_output_delay 0 [get_ports {sma_out sma_term sma_term_en}] +#set_false_path -from [get_ports {sma_in}] +#set_input_delay 0 [get_ports {sma_in}] + +# SFP+ Interfaces +#set_property -dict {LOC D2 } [get_ports sfp_1_rx_p] ;# MGTHRXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC D1 } [get_ports sfp_1_rx_n] ;# MGTHRXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC E4 } [get_ports sfp_1_tx_p] ;# MGTHTXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC E3 } [get_ports sfp_1_tx_n] ;# MGTHTXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC C4 } [get_ports sfp_2_rx_p] ;# MGTHRXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC C3 } [get_ports sfp_2_rx_n] ;# MGTHRXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC D6 } [get_ports sfp_2_tx_p] ;# MGTHTXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC D5 } [get_ports sfp_2_tx_n] ;# MGTHTXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC H6 } [get_ports sfp_mgt_refclk_p] ;# MGTREFCLK0P_227 from X2 +#set_property -dict {LOC H5 } [get_ports sfp_mgt_refclk_n] ;# MGTREFCLK0N_227 from X2 +#set_property -dict {LOC AA12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_1_tx_disable] +#set_property -dict {LOC W14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_2_tx_disable] +#set_property -dict {LOC C24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_1_npres] +#set_property -dict {LOC D24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_2_npres] +#set_property -dict {LOC W13 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_1_los] +#set_property -dict {LOC AB12 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_2_los] +#set_property -dict {LOC B25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_1_rs] +#set_property -dict {LOC D25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_2_rs] +#set_property -dict {LOC W11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_i2c_scl] +#set_property -dict {LOC Y11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_1_i2c_sda] +#set_property -dict {LOC Y13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_2_i2c_sda] + +# 161.1328125 MHz MGT reference clock +#create_clock -period 6.206 -name sfp_mgt_refclk [get_ports sfp_mgt_refclk_p] + +#set_false_path -to [get_ports {sfp_1_tx_disable sfp_2_tx_disable sfp_1_rs sfp_2_rs}] +#set_output_delay 0 [get_ports {sfp_1_tx_disable sfp_2_tx_disable sfp_1_rs sfp_2_rs}] +#set_false_path -from [get_ports {sfp_1_npres sfp_2_npres sfp_1_los sfp_2_los}] +#set_input_delay 0 [get_ports {sfp_1_npres sfp_2_npres sfp_1_los sfp_2_los}] + +#set_false_path -to [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}] +#set_output_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}] +#set_false_path -from [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}] +#set_input_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}] + +# I2C interface +#set_property -dict {LOC B26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl] +#set_property -dict {LOC C26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda] + +#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl}] +#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}] +#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 P2 } [get_ports {pcie_rx_p[0]}] ;# MGTHRXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTHRXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC R4 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC R3 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTHRXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTHRXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC U4 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC U3 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTHRXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTHRXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC W4 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC W3 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTHRXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTHRXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC AA4 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC AA3 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTHRXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTHRXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AB6 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AB5 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTHRXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTHRXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AC4 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AC3 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTHRXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTHRXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AD6 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AD5 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTHRXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTHRXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AF6 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC AF5 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +set_property -dict {LOC T6 } [get_ports pcie_mgt_refclk_p] ;# MGTREFCLK0P_225 +set_property -dict {LOC T5 } [get_ports pcie_mgt_refclk_n] ;# MGTREFCLK0N_225 +set_property -dict {LOC AC22 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_mgt_refclk_p] + +set_false_path -from [get_ports {pcie_reset_n}] +set_input_delay 0 [get_ports {pcie_reset_n}] + +# BPI flash +#set_property -dict {LOC AE10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[0]}] +#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[1]}] +#set_property -dict {LOC AD10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[2]}] +#set_property -dict {LOC AD9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[3]}] +#set_property -dict {LOC AC11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[4]}] +#set_property -dict {LOC AF10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[5]}] +#set_property -dict {LOC AF14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[6]}] +#set_property -dict {LOC AE12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[7]}] +#set_property -dict {LOC AD14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[8]}] +#set_property -dict {LOC AF13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[9]}] +#set_property -dict {LOC AE13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[10]}] +#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[11]}] +#set_property -dict {LOC AC13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[12]}] +#set_property -dict {LOC AD13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[13]}] +#set_property -dict {LOC AA14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[14]}] +#set_property -dict {LOC AB15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[15]}] +#set_property -dict {LOC AD11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[0]}] +#set_property -dict {LOC AE11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[1]}] +#set_property -dict {LOC AF12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[2]}] +#set_property -dict {LOC AB11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[3]}] +#set_property -dict {LOC AB9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[4]}] +#set_property -dict {LOC AB14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[5]}] +#set_property -dict {LOC AA10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[6]}] +#set_property -dict {LOC AA9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[7]}] +#set_property -dict {LOC W10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[8]}] +#set_property -dict {LOC AA13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[9]}] +#set_property -dict {LOC Y15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[10]}] +#set_property -dict {LOC AC12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[11]}] +#set_property -dict {LOC V12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[12]}] +#set_property -dict {LOC V11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[13]}] +#set_property -dict {LOC Y12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[14]}] +#set_property -dict {LOC W9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[15]}] +#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[16]}] +#set_property -dict {LOC W8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[17]}] +#set_property -dict {LOC W15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[18]}] +#set_property -dict {LOC AA15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[19]}] +#set_property -dict {LOC AE16 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[20]}] +#set_property -dict {LOC AF15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[21]}] +#set_property -dict {LOC AE15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[22]}] +#set_property -dict {LOC AD15 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {flash_region}] +#set_property -dict {LOC AC9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_ce_n}] +#set_property -dict {LOC AC14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_oe_n}] +#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_we_n}] +#set_property -dict {LOC Y10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_adv_n}] + +#set_false_path -to [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}] +#set_output_delay 0 [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}] +#set_false_path -from [get_ports {flash_dq[*]}] +#set_input_delay 0 [get_ports {flash_dq[*]}] diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga/Makefile b/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga/Makefile new file mode 100644 index 000000000..ee821b8fb --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/fpga/Makefile @@ -0,0 +1,94 @@ + +# FPGA settings +FPGA_PART = xcku035-fbva676-2-e +FPGA_TOP = fpga +FPGA_ARCH = kintexu + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/common/example_core_pcie_us.v +SYN_FILES += rtl/common/example_core_pcie.v +SYN_FILES += rtl/common/example_core.v +SYN_FILES += rtl/common/axi_ram.v +SYN_FILES += lib/pcie/rtl/pcie_us_if.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v +SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v +SYN_FILES += lib/pcie/rtl/pcie_us_msi.v +SYN_FILES += lib/pcie/rtl/pcie_axil_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v +SYN_FILES += lib/pcie/rtl/dma_psdpram.v +SYN_FILES += lib/pcie/rtl/arbiter.v +SYN_FILES += lib/pcie/rtl/priority_encoder.v +SYN_FILES += lib/pcie/rtl/pulse_merge.v + +# XDC files +XDC_FILES = fpga.xdc + +# IP +IP_TCL_FILES = ip/pcie3_ultrascale_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +%.mcs %.prm: %.bit + echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x00800000 $*.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 {s29gl256p-bpi-x16}] 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.BPI_RS_PINS {24:23} [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 + diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/ip/pcie3_ultrascale_0.tcl b/fpga/lib/pcie/example/ExaNIC_X10/fpga/ip/pcie3_ultrascale_0.tcl new file mode 100644 index 000000000..d39fa31a0 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/ip/pcie3_ultrascale_0.tcl @@ -0,0 +1,31 @@ + +create_ip -name pcie3_ultrascale -vendor xilinx.com -library ip -module_name pcie3_ultrascale_0 + +set_property -dict [list \ + CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \ + CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \ + CONFIG.AXISTEN_IF_RC_STRADDLE {false} \ + CONFIG.axisten_if_width {256_bit} \ + CONFIG.extended_tag_field {true} \ + CONFIG.axisten_freq {250} \ + CONFIG.PF0_CLASS_CODE {058000} \ + CONFIG.PF0_DEVICE_ID {0001} \ + CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ + CONFIG.PF0_SUBSYSTEM_ID {0003} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} \ + CONFIG.pf0_bar0_64bit {true} \ + CONFIG.pf0_bar0_prefetchable {true} \ + CONFIG.pf0_bar0_scale {Megabytes} \ + CONFIG.pf0_bar0_size {16} \ + CONFIG.pf0_bar2_64bit {true} \ + CONFIG.pf0_bar2_prefetchable {true} \ + CONFIG.pf0_bar2_enabled {true} \ + CONFIG.pf0_bar2_type {Memory} \ + CONFIG.pf0_bar2_scale {Megabytes} \ + CONFIG.pf0_bar2_size {16} \ + CONFIG.PF0_INTERRUPT_PIN {NONE} \ + CONFIG.PF0_MSIX_CAP_TABLE_BIR {BAR_0} \ + CONFIG.PF0_MSIX_CAP_PBA_BIR {BAR_0} \ + CONFIG.vendor_id {1234} \ + CONFIG.en_msi_per_vec_masking {true} \ +] [get_ips pcie3_ultrascale_0] diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/lib/pcie b/fpga/lib/pcie/example/ExaNIC_X10/fpga/lib/pcie new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/lib/pcie @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/common b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/common new file mode 120000 index 000000000..e60fada70 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/common @@ -0,0 +1 @@ +../../../common/rtl/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga.v b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga.v new file mode 100644 index 000000000..209e1325f --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga.v @@ -0,0 +1,449 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga ( + /* + * GPIO + */ + output wire [1:0] sfp_1_led, + output wire [1:0] sfp_2_led, + output wire [1:0] sma_led, + + /* + * PCI express + */ + input wire [7:0] pcie_rx_p, + input wire [7:0] pcie_rx_n, + output wire [7:0] pcie_tx_p, + output wire [7:0] pcie_tx_n, + input wire pcie_mgt_refclk_p, + input wire pcie_mgt_refclk_n, + input wire pcie_reset_n +); + +parameter AXIS_PCIE_DATA_WIDTH = 256; +parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); +parameter AXIS_PCIE_RC_USER_WIDTH = 75; +parameter AXIS_PCIE_RQ_USER_WIDTH = 60; +parameter AXIS_PCIE_CQ_USER_WIDTH = 85; +parameter AXIS_PCIE_CC_USER_WIDTH = 33; + +parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6; +parameter RQ_SEQ_NUM_ENABLE = 1; + +parameter PCIE_TAG_COUNT = 64; +parameter BAR0_APERTURE = 24; +parameter BAR2_APERTURE = 24; + +// PCIe +wire pcie_user_clk; +wire pcie_user_reset; + +wire pcie_sys_clk; +wire pcie_sys_clk_gt; + +IBUFDS_GTE3 #( + .REFCLK_HROW_CK_SEL(2'b00) +) +ibufds_gte3_pcie_mgt_refclk_inst ( + .I (pcie_mgt_refclk_p), + .IB (pcie_mgt_refclk_n), + .CEB (1'b0), + .O (pcie_sys_clk_gt), + .ODIV2 (pcie_sys_clk) +); + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rq_tkeep; +wire axis_rq_tlast; +wire axis_rq_tready; +wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] axis_rq_tuser; +wire axis_rq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rc_tkeep; +wire axis_rc_tlast; +wire axis_rc_tready; +wire [AXIS_PCIE_RC_USER_WIDTH-1:0] axis_rc_tuser; +wire axis_rc_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cq_tkeep; +wire axis_cq_tlast; +wire axis_cq_tready; +wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] axis_cq_tuser; +wire axis_cq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cc_tkeep; +wire axis_cc_tlast; +wire axis_cc_tready; +wire [AXIS_PCIE_CC_USER_WIDTH-1:0] axis_cc_tuser; +wire axis_cc_tvalid; + +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num; +wire pcie_rq_seq_num_vld; + +// ila_0 rq_ila ( +// .clk(pcie_user_clk), +// .probe0(axis_rq_tdata), +// .probe1(axis_rq_tkeep), +// .probe2(axis_rq_tlast), +// .probe3(axis_rq_tready), +// .probe4(axis_rq_tuser), +// .probe5(axis_rq_tvalid) +// ); + +// ila_0 rc_ila ( +// .clk(pcie_user_clk), +// .probe0(axis_rc_tdata), +// .probe1(axis_rc_tkeep), +// .probe2(axis_rc_tlast), +// .probe3(axis_rc_tready), +// .probe4(axis_rc_tuser), +// .probe5(axis_rc_tvalid) +// ); + +wire [2:0] cfg_max_payload; +wire [2:0] cfg_max_read_req; + +wire [18:0] cfg_mgmt_addr; +wire cfg_mgmt_write; +wire [31:0] cfg_mgmt_write_data; +wire [3:0] cfg_mgmt_byte_enable; +wire cfg_mgmt_read; +wire [31:0] cfg_mgmt_read_data; +wire cfg_mgmt_read_write_done; + +wire [7:0] cfg_fc_ph; +wire [11:0] cfg_fc_pd; +wire [7:0] cfg_fc_nph; +wire [11:0] cfg_fc_npd; +wire [7:0] cfg_fc_cplh; +wire [11:0] cfg_fc_cpld; +wire [2:0] cfg_fc_sel; + +wire [3:0] cfg_interrupt_msi_enable; +wire [7:0] cfg_interrupt_msi_vf_enable; +wire [11:0] cfg_interrupt_msi_mmenable; +wire cfg_interrupt_msi_mask_update; +wire [31:0] cfg_interrupt_msi_data; +wire [3:0] cfg_interrupt_msi_select; +wire [31:0] cfg_interrupt_msi_int; +wire [31:0] cfg_interrupt_msi_pending_status; +wire cfg_interrupt_msi_pending_status_data_enable; +wire [3:0] cfg_interrupt_msi_pending_status_function_num; +wire cfg_interrupt_msi_sent; +wire cfg_interrupt_msi_fail; +wire [2:0] cfg_interrupt_msi_attr; +wire cfg_interrupt_msi_tph_present; +wire [1:0] cfg_interrupt_msi_tph_type; +wire [8:0] cfg_interrupt_msi_tph_st_tag; +wire [3:0] cfg_interrupt_msi_function_number; + +wire status_error_cor; +wire status_error_uncor; + +pcie3_ultrascale_0 +pcie3_ultrascale_inst ( + .pci_exp_txn(pcie_tx_n), + .pci_exp_txp(pcie_tx_p), + .pci_exp_rxn(pcie_rx_n), + .pci_exp_rxp(pcie_rx_p), + .user_clk(pcie_user_clk), + .user_reset(pcie_user_reset), + .user_lnk_up(), + + .s_axis_rq_tdata(axis_rq_tdata), + .s_axis_rq_tkeep(axis_rq_tkeep), + .s_axis_rq_tlast(axis_rq_tlast), + .s_axis_rq_tready(axis_rq_tready), + .s_axis_rq_tuser(axis_rq_tuser), + .s_axis_rq_tvalid(axis_rq_tvalid), + + .m_axis_rc_tdata(axis_rc_tdata), + .m_axis_rc_tkeep(axis_rc_tkeep), + .m_axis_rc_tlast(axis_rc_tlast), + .m_axis_rc_tready(axis_rc_tready), + .m_axis_rc_tuser(axis_rc_tuser), + .m_axis_rc_tvalid(axis_rc_tvalid), + + .m_axis_cq_tdata(axis_cq_tdata), + .m_axis_cq_tkeep(axis_cq_tkeep), + .m_axis_cq_tlast(axis_cq_tlast), + .m_axis_cq_tready(axis_cq_tready), + .m_axis_cq_tuser(axis_cq_tuser), + .m_axis_cq_tvalid(axis_cq_tvalid), + + .s_axis_cc_tdata(axis_cc_tdata), + .s_axis_cc_tkeep(axis_cc_tkeep), + .s_axis_cc_tlast(axis_cc_tlast), + .s_axis_cc_tready(axis_cc_tready), + .s_axis_cc_tuser(axis_cc_tuser), + .s_axis_cc_tvalid(axis_cc_tvalid), + + .pcie_rq_seq_num(pcie_rq_seq_num), + .pcie_rq_seq_num_vld(pcie_rq_seq_num_vld), + .pcie_rq_tag(), + .pcie_rq_tag_av(), + .pcie_rq_tag_vld(), + + .pcie_tfc_nph_av(), + .pcie_tfc_npd_av(), + + .pcie_cq_np_req(1'b1), + .pcie_cq_np_req_count(), + + .cfg_phy_link_down(), + .cfg_phy_link_status(), + .cfg_negotiated_width(), + .cfg_current_speed(), + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_function_status(), + .cfg_function_power_state(), + .cfg_vf_status(), + .cfg_vf_power_state(), + .cfg_link_power_state(), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + .cfg_mgmt_type1_cfg_reg_access(1'b0), + + .cfg_err_cor_out(), + .cfg_err_nonfatal_out(), + .cfg_err_fatal_out(), + .cfg_local_error(), + .cfg_ltr_enable(), + .cfg_ltssm_state(), + .cfg_rcb_status(), + .cfg_dpa_substate_change(), + .cfg_obff_enable(), + .cfg_pl_status_change(), + .cfg_tph_requester_enable(), + .cfg_tph_st_mode(), + .cfg_vf_tph_requester_enable(), + .cfg_vf_tph_st_mode(), + + .cfg_msg_received(), + .cfg_msg_received_data(), + .cfg_msg_received_type(), + .cfg_msg_transmit(1'b0), + .cfg_msg_transmit_type(3'd0), + .cfg_msg_transmit_data(32'd0), + .cfg_msg_transmit_done(), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_per_func_status_control(3'd0), + .cfg_per_func_status_data(), + .cfg_per_function_number(4'd0), + .cfg_per_function_output_request(1'b0), + .cfg_per_function_update_done(), + + .cfg_dsn(64'd0), + + .cfg_power_state_change_ack(1'b1), + .cfg_power_state_change_interrupt(), + + .cfg_err_cor_in(status_error_cor), + .cfg_err_uncor_in(status_error_uncor), + .cfg_flr_in_process(), + .cfg_flr_done(4'd0), + .cfg_vf_flr_in_process(), + .cfg_vf_flr_done(8'd0), + + .cfg_link_training_enable(1'b1), + + .cfg_interrupt_int(4'd0), + .cfg_interrupt_pending(4'd0), + .cfg_interrupt_sent(), + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_hot_reset_out(), + + .cfg_config_space_enable(1'b1), + .cfg_req_pm_transition_l23_ready(1'b0), + .cfg_hot_reset_in(1'b0), + + .cfg_ds_port_number(8'd0), + .cfg_ds_bus_number(8'd0), + .cfg_ds_device_number(5'd0), + .cfg_ds_function_number(3'd0), + + .cfg_subsys_vend_id(16'h1234), + + .sys_clk(pcie_sys_clk), + .sys_clk_gt(pcie_sys_clk_gt), + .sys_reset(pcie_reset_n), + .pcie_perstn1_in(1'b0), + .pcie_perstn0_out(), + .pcie_perstn1_out(), + + .int_qpll1lock_out(), + .int_qpll1outrefclk_out(), + .int_qpll1outclk_out(), + .phy_rdy_out() +); + +fpga_core #( + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +core_inst ( + /* + * Clock: 250 MHz + * Synchronous reset + */ + .clk(pcie_user_clk), + .rst(pcie_user_reset), + /* + * GPIO + */ + .sfp_1_led(sfp_1_led), + .sfp_2_led(sfp_2_led), + .sma_led(sma_led), + /* + * PCIe + */ + .m_axis_rq_tdata(axis_rq_tdata), + .m_axis_rq_tkeep(axis_rq_tkeep), + .m_axis_rq_tlast(axis_rq_tlast), + .m_axis_rq_tready(axis_rq_tready), + .m_axis_rq_tuser(axis_rq_tuser), + .m_axis_rq_tvalid(axis_rq_tvalid), + + .s_axis_rc_tdata(axis_rc_tdata), + .s_axis_rc_tkeep(axis_rc_tkeep), + .s_axis_rc_tlast(axis_rc_tlast), + .s_axis_rc_tready(axis_rc_tready), + .s_axis_rc_tuser(axis_rc_tuser), + .s_axis_rc_tvalid(axis_rc_tvalid), + + .s_axis_cq_tdata(axis_cq_tdata), + .s_axis_cq_tkeep(axis_cq_tkeep), + .s_axis_cq_tlast(axis_cq_tlast), + .s_axis_cq_tready(axis_cq_tready), + .s_axis_cq_tuser(axis_cq_tuser), + .s_axis_cq_tvalid(axis_cq_tvalid), + + .m_axis_cc_tdata(axis_cc_tdata), + .m_axis_cc_tkeep(axis_cc_tkeep), + .m_axis_cc_tlast(axis_cc_tlast), + .m_axis_cc_tready(axis_cc_tready), + .m_axis_cc_tuser(axis_cc_tuser), + .m_axis_cc_tvalid(axis_cc_tvalid), + + .s_axis_rq_seq_num(pcie_rq_seq_num), + .s_axis_rq_seq_num_valid(pcie_rq_seq_num_vld), + + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga_core.v b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..de673de2c --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/fpga_core.v @@ -0,0 +1,274 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter AXIS_PCIE_DATA_WIDTH = 256, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = 75, + parameter AXIS_PCIE_RQ_USER_WIDTH = 60, + parameter AXIS_PCIE_CQ_USER_WIDTH = 85, + parameter AXIS_PCIE_CC_USER_WIDTH = 33, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter RQ_SEQ_NUM_ENABLE = 1, + parameter PCIE_TAG_COUNT = 64, + parameter BAR0_APERTURE = 24, + parameter BAR2_APERTURE = 24 +) +( + /* + * Clock: 250 MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [1:0] sfp_1_led, + output wire [1:0] sfp_2_led, + output wire [1:0] sma_led, + + /* + * PCIe + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep, + output wire m_axis_rq_tlast, + input wire m_axis_rq_tready, + output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser, + output wire m_axis_rq_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep, + input wire s_axis_rc_tlast, + output wire s_axis_rc_tready, + input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser, + input wire s_axis_rc_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep, + input wire s_axis_cq_tlast, + output wire s_axis_cq_tready, + input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser, + input wire s_axis_cq_tvalid, + + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep, + output wire m_axis_cc_tlast, + input wire m_axis_cc_tready, + output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser, + output wire m_axis_cc_tvalid, + + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num, + input wire s_axis_rq_seq_num_valid, + + input wire [2:0] cfg_max_payload, + input wire [2:0] cfg_max_read_req, + + output wire [18:0] cfg_mgmt_addr, + output wire cfg_mgmt_write, + output wire [31:0] cfg_mgmt_write_data, + output wire [3:0] cfg_mgmt_byte_enable, + output wire cfg_mgmt_read, + input wire [31:0] cfg_mgmt_read_data, + input wire cfg_mgmt_read_write_done, + + input wire [7:0] cfg_fc_ph, + input wire [11:0] cfg_fc_pd, + input wire [7:0] cfg_fc_nph, + input wire [11:0] cfg_fc_npd, + input wire [7:0] cfg_fc_cplh, + input wire [11:0] cfg_fc_cpld, + output wire [2:0] cfg_fc_sel, + + input wire [3:0] cfg_interrupt_msi_enable, + input wire [7:0] cfg_interrupt_msi_vf_enable, + input wire [11:0] cfg_interrupt_msi_mmenable, + input wire cfg_interrupt_msi_mask_update, + input wire [31:0] cfg_interrupt_msi_data, + output wire [3:0] cfg_interrupt_msi_select, + output wire [31:0] cfg_interrupt_msi_int, + output wire [31:0] cfg_interrupt_msi_pending_status, + output wire cfg_interrupt_msi_pending_status_data_enable, + output wire [3:0] cfg_interrupt_msi_pending_status_function_num, + input wire cfg_interrupt_msi_sent, + input wire cfg_interrupt_msi_fail, + output wire [2:0] cfg_interrupt_msi_attr, + output wire cfg_interrupt_msi_tph_present, + output wire [1:0] cfg_interrupt_msi_tph_type, + output wire [8:0] cfg_interrupt_msi_tph_st_tag, + output wire [3:0] cfg_interrupt_msi_function_number, + + output wire status_error_cor, + output wire status_error_uncor +); + +assign sfp_1_led = 2'b00; +assign sfp_2_led = 2'b00; +assign sma_led = 2'b00; + +example_core_pcie_us #( + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(PCIE_TAG_COUNT), + .READ_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)), + .READ_TX_FC_ENABLE(1), + .WRITE_OP_TABLE_SIZE(2**(RQ_SEQ_NUM_WIDTH-1)), + .WRITE_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)), + .WRITE_TX_FC_ENABLE(1), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +example_core_pcie_us_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI input (RC) + */ + .s_axis_rc_tdata(s_axis_rc_tdata), + .s_axis_rc_tkeep(s_axis_rc_tkeep), + .s_axis_rc_tvalid(s_axis_rc_tvalid), + .s_axis_rc_tready(s_axis_rc_tready), + .s_axis_rc_tlast(s_axis_rc_tlast), + .s_axis_rc_tuser(s_axis_rc_tuser), + + /* + * AXI output (RQ) + */ + .m_axis_rq_tdata(m_axis_rq_tdata), + .m_axis_rq_tkeep(m_axis_rq_tkeep), + .m_axis_rq_tvalid(m_axis_rq_tvalid), + .m_axis_rq_tready(m_axis_rq_tready), + .m_axis_rq_tlast(m_axis_rq_tlast), + .m_axis_rq_tuser(m_axis_rq_tuser), + + /* + * AXI input (CQ) + */ + .s_axis_cq_tdata(s_axis_cq_tdata), + .s_axis_cq_tkeep(s_axis_cq_tkeep), + .s_axis_cq_tvalid(s_axis_cq_tvalid), + .s_axis_cq_tready(s_axis_cq_tready), + .s_axis_cq_tlast(s_axis_cq_tlast), + .s_axis_cq_tuser(s_axis_cq_tuser), + + /* + * AXI output (CC) + */ + .m_axis_cc_tdata(m_axis_cc_tdata), + .m_axis_cc_tkeep(m_axis_cc_tkeep), + .m_axis_cc_tvalid(m_axis_cc_tvalid), + .m_axis_cc_tready(m_axis_cc_tready), + .m_axis_cc_tlast(m_axis_cc_tlast), + .m_axis_cc_tuser(m_axis_cc_tuser), + + /* + * Transmit sequence number input + */ + .s_axis_rq_seq_num_0(s_axis_rq_seq_num), + .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid), + .s_axis_rq_seq_num_1(0), + .s_axis_rq_seq_num_valid_1(0), + + /* + * Flow control + */ + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + /* + * Configuration interface + */ + .cfg_mgmt_addr(cfg_mgmt_addr[9:0]), + .cfg_mgmt_function_number(cfg_mgmt_addr[17:10]), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + /* + * Interrupt interface + */ + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * Configuration + */ + .cfg_max_read_req(cfg_max_read_req), + .cfg_max_payload(cfg_max_payload), + + /* + * Status + */ + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor) +); + +assign cfg_mgmt_addr[18] = 1'b0; + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_reset.v b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..1fd24d361 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_reset.v @@ -0,0 +1,56 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_signal.v b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/rtl/sync_signal.v @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/Makefile b/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..2cd4c6b21 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/Makefile @@ -0,0 +1,123 @@ +# 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 += ../../rtl/common/example_core_pcie_us.v +VERILOG_SOURCES += ../../rtl/common/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/common/example_core.v +VERILOG_SOURCES += ../../rtl/common/axi_ram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rc.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rq.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cq.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cc.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_RQ_SEQ_NUM_ENABLE ?= 1 +export PARAM_PCIE_TAG_COUNT ?= 64 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py b/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..40aca6918 --- /dev/null +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,381 @@ +""" + +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 + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.axi import AxiStreamBus +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag + # pcie_rq_tag_av + # pcie_rq_tag_vld + + # Requester Completion Interface + rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), + + # Completer reQuest Interface + cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**24) + self.dev.functions[0].configure_bar(2, 2**24) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "example_core_pcie_us.v"), + os.path.join(rtl_dir, "common", "example_core_pcie.v"), + os.path.join(rtl_dir, "common", "example_core.v"), + os.path.join(rtl_dir, "common", "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['RQ_SEQ_NUM_ENABLE'] = 1 + parameters['PCIE_TAG_COUNT'] = 64 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/ExaNIC_X10/fpga_axi/ip/pcie3_ultrascale_0.tcl b/fpga/lib/pcie/example/ExaNIC_X10/fpga_axi/ip/pcie3_ultrascale_0.tcl index 89c2b7473..d39fa31a0 100644 --- a/fpga/lib/pcie/example/ExaNIC_X10/fpga_axi/ip/pcie3_ultrascale_0.tcl +++ b/fpga/lib/pcie/example/ExaNIC_X10/fpga_axi/ip/pcie3_ultrascale_0.tcl @@ -8,16 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_width {256_bit} \ CONFIG.extended_tag_field {true} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ - CONFIG.pf0_class_code_base {02} \ - CONFIG.pf0_class_code_sub {00} \ + CONFIG.PF0_SUBSYSTEM_ID {0003} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/ExaNIC_X25/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/ExaNIC_X25/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 863a2ca12..ba3d07176 100644 --- a/fpga/lib/pcie/example/ExaNIC_X25/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/ExaNIC_X25/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -9,16 +9,11 @@ set_property -dict [list \ CONFIG.axisten_if_width {256_bit} \ CONFIG.extended_tag_field {true} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_base {02} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {0009} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/README.md b/fpga/lib/pcie/example/S10MX_DK/fpga/README.md new file mode 100644 index 000000000..f777706b1 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/README.md @@ -0,0 +1,19 @@ +# Verilog PCIe Intel Stratix 10 MX Development Kit Example Design + +## Introduction + +This example design targets the Intel Stratix 10 MX Development Kit. + +The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design. + +* FPGA: 1SM21BHU2F53E1VG (8 GB HBM2) or 1SM21CHU1F53E1VG (16 GB HBM2) + +## How to build + +Run `make` to build. Ensure that the Intel Quartus Pro components are in PATH. + +Run `make` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled. + +## How to test + +Run `make program` to program the Stratix 10 MX development kit with Quartus Pro. Then load the driver with `insmod example.ko`. Check dmesg for the output. diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/common/quartus_pro.mk b/fpga/lib/pcie/example/S10MX_DK/fpga/common/quartus_pro.mk new file mode 100644 index 000000000..1fc1b6fe8 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/common/quartus_pro.mk @@ -0,0 +1,179 @@ +################################################################### +# +# Makefile for Intel Quartus Prime Pro +# +# Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. Stratix 10 DX) +# FPGA_DEVICE - FPGA device (e.g. 1SD280PT2F55E1VG) +# SYN_FILES - space-separated list of source files +# IP_FILES - space-separated list of IP files +# IP_TCL_FILES - space-separated list of TCL files for qsys-script +# QSF_FILES - space-separated list of settings files +# SDC_FILES - space-separated list of timing constraint files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = "Stratix 10 DX" +# FPGA_DEVICE = 1SD280PT2F55E1VG +# SYN_FILES = rtl/fpga.v +# QSF_FILES = fpga.qsf +# SDC_FILES = fpga.sdc +# include ../common/quartus_pro.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# output files to hang on to +.PRECIOUS: %.sof %.ipregen.rpt %.syn.rpt %.fit.rpt %.asm.rpt %.sta.rpt +.SECONDARY: + +# any project specific settings +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) + +IP_FILES_REL = $(patsubst %, ../%, $(IP_FILES)) +IP_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_FILES))) + +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) +IP_TCL_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_TCL_FILES))) +IP_TCL_FILES_IP_INT = $(patsubst %.tcl, ip/%.ip, $(notdir $(IP_TCL_FILES))) + +ifdef QSF_FILES + QSF_FILES_REL = $(patsubst %, ../%, $(QSF_FILES)) +else + QSF_FILES_REL = ../$(FPGA_TOP).qsf +endif + +SDC_FILES_REL = $(patsubst %, ../%, $(SDC_FILES)) + +ASSIGNMENT_FILES = $(FPGA_TOP).qpf $(FPGA_TOP).qsf + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and database +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).sof + +quartus: $(FPGA_TOP).qpf + quartus $(FPGA_TOP).qpf + +tmpclean: + -rm -rf defines.v + -rm -rf *.rpt *.summary *.done *.smsg *.chg smart.log *.htm *.eqn *.pin *.qsf *.qpf *.sld *.txt *.qws *.stp + -rm -rf ip db qdb incremental_db reconfig_mif tmp-clearbox synth_dumps .qsys_edit + +clean: tmpclean + -rm -rf *.sof *.pof *.jdi *.jic *.map + +distclean: clean + -rm -rf rev + +syn: smart.log output_files/$(PROJECT).syn.rpt +fit: smart.log output_files/$(PROJECT).fit.rpt +asm: smart.log output_files/$(PROJECT).asm.rpt +sta: smart.log output_files/$(PROJECT).sta.rpt +smart: smart.log + +################################################################### +# Executable Configuration +################################################################### + +IP_ARGS = --run_default_mode_op +SYN_ARGS = --read_settings_files=on --write_settings_files=off +FIT_ARGS = --read_settings_files=on --write_settings_files=off +ASM_ARGS = --read_settings_files=on --write_settings_files=off +STA_ARGS = + +################################################################### +# Target implementations +################################################################### + +STAMP = echo done > + +define COPY_IP_RULE +$(patsubst %, ip/%, $(notdir $(1))): $(1) + @mkdir -p ip + @cp -pv $(1) ip/ +endef +$(foreach l,$(IP_FILES_REL) $(IP_TCL_FILES_REL),$(eval $(call COPY_IP_RULE,$(l)))) + +define TCL_IP_GEN_RULE +$(patsubst %.tcl, %.ip, $(1)): $(1) + cd ip && qsys-script --script=$(notdir $(1)) +endef +$(foreach l,$(IP_TCL_FILES_INT),$(eval $(call TCL_IP_GEN_RULE,$(l)))) + +%.ipregen.rpt: $(FPGA_TOP).qpf $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT) + quartus_ipgenerate $(IP_ARGS) $(FPGA_TOP) + +%.syn.rpt: syn.chg %.ipregen.rpt $(SYN_FILES_REL) + quartus_syn $(SYN_ARGS) $(FPGA_TOP) + +%.fit.rpt: fit.chg %.syn.rpt $(SDC_FILES_REL) + quartus_fit $(FIT_ARGS) $(FPGA_TOP) + +%.sta.rpt: sta.chg %.fit.rpt + quartus_sta $(STA_ARGS) $(FPGA_TOP) + +%.asm.rpt: asm.chg %.sta.rpt + quartus_asm $(ASM_ARGS) $(FPGA_TOP) + mkdir -p rev + EXT=sof; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $*.$$EXT rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + +%.sof: smart.log %.asm.rpt + + +smart.log: $(ASSIGNMENT_FILES) + quartus_sh --determine_smart_action $(FPGA_TOP) > smart.log + +################################################################### +# Project initialization +################################################################### + +$(ASSIGNMENT_FILES): $(QSF_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT) + rm -f $(FPGA_TOP).qsf + quartus_sh --prepare -f $(FPGA_FAMILY) -d $(FPGA_DEVICE) -t $(FPGA_TOP) $(FPGA_TOP) + echo >> $(FPGA_TOP).qsf + echo >> $(FPGA_TOP).qsf + echo "# Source files" >> $(FPGA_TOP).qsf + for x in $(SYN_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT); do \ + case $${x##*.} in \ + v|V) echo set_global_assignment -name VERILOG_FILE $$x >> $(FPGA_TOP).qsf ;;\ + vhd|VHD) echo set_global_assignment -name VHDL_FILE $$x >> $(FPGA_TOP).qsf ;;\ + qip|QIP) echo set_global_assignment -name QIP_FILE $$x >> $(FPGA_TOP).qsf ;;\ + ip|IP) echo set_global_assignment -name IP_FILE $$x >> $(FPGA_TOP).qsf ;;\ + *) echo set_global_assignment -name SOURCE_FILE $$x >> $(FPGA_TOP).qsf ;;\ + esac; \ + done + echo >> $(FPGA_TOP).qsf + echo "# SDC files" >> $(FPGA_TOP).qsf + for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE $$x >> $(FPGA_TOP).qsf; done + for x in $(QSF_FILES_REL); do printf "\n#\n# Included QSF file $$x\n#\n" >> $(FPGA_TOP).qsf; cat $$x >> $(FPGA_TOP).qsf; done + +syn.chg: + $(STAMP) syn.chg +fit.chg: + $(STAMP) fit.chg +sta.chg: + $(STAMP) sta.chg +asm.chg: + $(STAMP) asm.chg diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.qsf b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.qsf new file mode 100644 index 000000000..abce536f1 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.qsf @@ -0,0 +1,660 @@ +# I/O constraints for the Intel Stratix 10 MX FPGA development board +# part: 1SM21BHU2F53E1VG (DK-DEV-1SMX-H-A with 8 GB HBM2) +# part: 1SM21CHU1F53E1VG (DK-DEV-1SMC-H-A with 16 GB HBM2) + +set_global_assignment -name USE_CONF_DONE SDM_IO16 +set_global_assignment -name USE_INIT_DONE SDM_IO0 +set_global_assignment -name USE_CVP_CONFDONE SDM_IO15 + +set_global_assignment -name USE_PWRMGT_SCL SDM_IO14 +set_global_assignment -name USE_PWRMGT_SDA SDM_IO11 +set_global_assignment -name PWRMGT_BUS_SPEED_MODE "100 KHZ" +set_global_assignment -name PWRMGT_SLAVE_DEVICE_TYPE OTHER +set_global_assignment -name PWRMGT_SLAVE_DEVICE0_ADDRESS 47 +set_global_assignment -name PWRMGT_SLAVE_DEVICE1_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE2_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE3_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE4_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE5_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE6_ADDRESS 00 +set_global_assignment -name PWRMGT_SLAVE_DEVICE7_ADDRESS 00 +set_global_assignment -name PWRMGT_TRANSLATED_VOLTAGE_VALUE_UNIT VOLTS +set_global_assignment -name PWRMGT_PAGE_COMMAND_ENABLE ON + +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 +set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION ON +set_global_assignment -name DEVICE_INITIALIZATION_CLOCK OSC_CLK_1_125MHZ +set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "ACTIVE SERIAL X4" +set_global_assignment -name ACTIVE_SERIAL_CLOCK AS_FREQ_100MHZ +set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_NCE_PIN OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name USE_CHECKSUM_AS_USERCODE ON +set_global_assignment -name GENERATE_PR_RBF_FILE ON +set_global_assignment -name ENABLE_ED_CRC_CHECK ON +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 +set_global_assignment -name MINIMUM_SEU_INTERVAL 10969 + +set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED" + +set_global_assignment -name PRESERVE_UNUSED_XCVR_CHANNEL ON + +# Clock and reset +set_location_assignment PIN_BE17 -to "clk_sys_50m_p" +set_location_assignment PIN_BD17 -to "clk_sys_50m_n" +set_location_assignment PIN_AU17 -to "clk_sys_100m_p" +set_location_assignment PIN_AU16 -to "clk_sys_100m_n" + +set_location_assignment PIN_AT13 -to "clk_core_bak_p" +set_location_assignment PIN_AU13 -to "clk_core_bak_n" + +set_location_assignment PIN_AR26 -to "clk_uib0_p" +set_location_assignment PIN_AP26 -to "clk_uib0_n" +set_location_assignment PIN_P27 -to "clk_uib1_p" +set_location_assignment PIN_R27 -to "clk_uib1_n" + +set_location_assignment PIN_AU31 -to "clk_esram0_p" +set_location_assignment PIN_AU32 -to "clk_esram0_n" +set_location_assignment PIN_V31 -to "clk_esram1_p" +set_location_assignment PIN_U31 -to "clk_esram1_n" + +set_location_assignment PIN_A42 -to "clk_ddr4_comp_p" +set_location_assignment PIN_B41 -to "clk_ddr4_comp_n" + +set_location_assignment PIN_B18 -to "clk_ddr4_dimm_p" +set_location_assignment PIN_C18 -to "clk_ddr4_dimm_n" + +set_instance_assignment -name IO_STANDARD LVDS -to "clk_sys_50m_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_sys_100m_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_core_bak_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_uib0_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_uib1_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_esram0_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_esram1_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_ddr4_comp_p" +set_instance_assignment -name IO_STANDARD LVDS -to "clk_ddr4_dimm_p" + +# Switches, buttons, LEDs +set_location_assignment PIN_BL14 -to "cpu_resetn" + +set_location_assignment PIN_BH11 -to "user_led[3]" +set_location_assignment PIN_BG11 -to "user_led[2]" +set_location_assignment PIN_BF12 -to "user_led[1]" +set_location_assignment PIN_BG12 -to "user_led[0]" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "user_led[*]" + +# I2C +set_location_assignment PIN_BE14 -to "main_i2c_scl" +set_location_assignment PIN_BF13 -to "main_i2c_sda" +set_location_assignment PIN_D29 -to "ddr4_dimm_sda" +set_location_assignment PIN_H30 -to "ddr4_dimm_scl" +set_location_assignment PIN_BH14 -to "pcie_ep_i2c_sda" +set_location_assignment PIN_BH15 -to "pcie_ep_i2c_scl" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "main_i2c_scl" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "main_i2c_sda" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "ddr4_dimm_sda" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "ddr4_dimm_scl" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_ep_i2c_sda" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_ep_i2c_scl" + +# PCIe EP +set_location_assignment PIN_BH45 -to "pcie_ep_tx_p[0]" +set_location_assignment PIN_BH44 -to "pcie_ep_tx_n[0]" +set_location_assignment PIN_BL47 -to "pcie_ep_rx_p[0]" +set_location_assignment PIN_BL46 -to "pcie_ep_rx_n[0]" +set_location_assignment PIN_BJ47 -to "pcie_ep_tx_p[1]" +set_location_assignment PIN_BJ46 -to "pcie_ep_tx_n[1]" +set_location_assignment PIN_BK49 -to "pcie_ep_rx_p[1]" +set_location_assignment PIN_BK48 -to "pcie_ep_rx_n[1]" +set_location_assignment PIN_BG47 -to "pcie_ep_tx_p[2]" +set_location_assignment PIN_BG46 -to "pcie_ep_tx_n[2]" +set_location_assignment PIN_BH49 -to "pcie_ep_rx_p[2]" +set_location_assignment PIN_BH48 -to "pcie_ep_rx_n[2]" +set_location_assignment PIN_BF45 -to "pcie_ep_tx_p[3]" +set_location_assignment PIN_BF44 -to "pcie_ep_tx_n[3]" +set_location_assignment PIN_BG51 -to "pcie_ep_rx_p[3]" +set_location_assignment PIN_BG50 -to "pcie_ep_rx_n[3]" +set_location_assignment PIN_BE47 -to "pcie_ep_tx_p[4]" +set_location_assignment PIN_BE46 -to "pcie_ep_tx_n[4]" +set_location_assignment PIN_BF49 -to "pcie_ep_rx_p[4]" +set_location_assignment PIN_BF48 -to "pcie_ep_rx_n[4]" +set_location_assignment PIN_BD45 -to "pcie_ep_tx_p[5]" +set_location_assignment PIN_BD44 -to "pcie_ep_tx_n[5]" +set_location_assignment PIN_BE51 -to "pcie_ep_rx_p[5]" +set_location_assignment PIN_BE50 -to "pcie_ep_rx_n[5]" +set_location_assignment PIN_BB45 -to "pcie_ep_tx_p[6]" +set_location_assignment PIN_BB44 -to "pcie_ep_tx_n[6]" +set_location_assignment PIN_BD49 -to "pcie_ep_rx_p[6]" +set_location_assignment PIN_BD48 -to "pcie_ep_rx_n[6]" +set_location_assignment PIN_BC47 -to "pcie_ep_tx_p[7]" +set_location_assignment PIN_BC46 -to "pcie_ep_tx_n[7]" +set_location_assignment PIN_BC51 -to "pcie_ep_rx_p[7]" +set_location_assignment PIN_BC50 -to "pcie_ep_rx_n[7]" +set_location_assignment PIN_BA47 -to "pcie_ep_tx_p[8]" +set_location_assignment PIN_BA46 -to "pcie_ep_tx_n[8]" +set_location_assignment PIN_BB49 -to "pcie_ep_rx_p[8]" +set_location_assignment PIN_BB48 -to "pcie_ep_rx_n[8]" +set_location_assignment PIN_AY45 -to "pcie_ep_tx_p[9]" +set_location_assignment PIN_AY44 -to "pcie_ep_tx_n[9]" +set_location_assignment PIN_BA51 -to "pcie_ep_rx_p[9]" +set_location_assignment PIN_BA50 -to "pcie_ep_rx_n[9]" +set_location_assignment PIN_AW47 -to "pcie_ep_tx_p[10]" +set_location_assignment PIN_AW46 -to "pcie_ep_tx_n[10]" +set_location_assignment PIN_AY49 -to "pcie_ep_rx_p[10]" +set_location_assignment PIN_AY48 -to "pcie_ep_rx_n[10]" +set_location_assignment PIN_AV45 -to "pcie_ep_tx_p[11]" +set_location_assignment PIN_AV44 -to "pcie_ep_tx_n[11]" +set_location_assignment PIN_AW51 -to "pcie_ep_rx_p[11]" +set_location_assignment PIN_AW50 -to "pcie_ep_rx_n[11]" +set_location_assignment PIN_AU47 -to "pcie_ep_tx_p[12]" +set_location_assignment PIN_AU46 -to "pcie_ep_tx_n[12]" +set_location_assignment PIN_AV49 -to "pcie_ep_rx_p[12]" +set_location_assignment PIN_AV48 -to "pcie_ep_rx_n[12]" +set_location_assignment PIN_AT45 -to "pcie_ep_tx_p[13]" +set_location_assignment PIN_AT44 -to "pcie_ep_tx_n[13]" +set_location_assignment PIN_AU51 -to "pcie_ep_rx_p[13]" +set_location_assignment PIN_AU50 -to "pcie_ep_rx_n[13]" +set_location_assignment PIN_AR47 -to "pcie_ep_tx_p[14]" +set_location_assignment PIN_AR46 -to "pcie_ep_tx_n[14]" +set_location_assignment PIN_AT49 -to "pcie_ep_rx_p[14]" +set_location_assignment PIN_AT48 -to "pcie_ep_rx_n[14]" +set_location_assignment PIN_AP45 -to "pcie_ep_tx_p[15]" +set_location_assignment PIN_AP44 -to "pcie_ep_tx_n[15]" +set_location_assignment PIN_AR51 -to "pcie_ep_rx_p[15]" +set_location_assignment PIN_AR50 -to "pcie_ep_rx_n[15]" + +set_location_assignment PIN_AW43 -to "refclk_pcie_ep_p" +set_location_assignment PIN_AW42 -to "refclk_pcie_ep_n" + +set_location_assignment PIN_AR43 -to "refclk_pcie_ep_edge_p" +set_location_assignment PIN_AR42 -to "refclk_pcie_ep_edge_n" + +set_location_assignment PIN_BA43 -to "refclk_pcie_ep1_p" +set_location_assignment PIN_BA42 -to "refclk_pcie_ep1_n" + +set_location_assignment PIN_BH16 -to "pcie_ep_waken" + +set_location_assignment PIN_AH39 -to "s10_pcie_perstn0" +set_location_assignment PIN_BL10 -to "s10_pcie_perstn1" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_ep_tx_p[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_ep_rx_p[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_ep_tx_p[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_ep_rx_p[*]" + +set_instance_assignment -name IO_STANDARD "HCSL" -to "refclk_pcie_ep_p" +set_instance_assignment -name IO_STANDARD "HCSL" -to "refclk_pcie_ep_edge_p" +set_instance_assignment -name IO_STANDARD "HCSL" -to "refclk_pcie_ep1_p" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_ep_waken" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "s10_pcie_perstn0" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "s10_pcie_perstn0" +set_instance_assignment -name USE_AS_3V_GPIO ON -to "s10_pcie_perstn1" +set_instance_assignment -name IO_STANDARD "2.5 V" -to "s10_pcie_perstn1" + +# PCIe RP +set_location_assignment PIN_BL5 -to "pcie_rp_tx_p[0]" +set_location_assignment PIN_BL6 -to "pcie_rp_tx_n[0]" +set_location_assignment PIN_BH7 -to "pcie_rp_rx_p[0]" +set_location_assignment PIN_BH8 -to "pcie_rp_rx_n[0]" +set_location_assignment PIN_BK3 -to "pcie_rp_tx_p[1]" +set_location_assignment PIN_BK4 -to "pcie_rp_tx_n[1]" +set_location_assignment PIN_BJ5 -to "pcie_rp_rx_p[1]" +set_location_assignment PIN_BJ6 -to "pcie_rp_rx_n[1]" +set_location_assignment PIN_BH3 -to "pcie_rp_tx_p[2]" +set_location_assignment PIN_BH4 -to "pcie_rp_tx_n[2]" +set_location_assignment PIN_BG6 -to "pcie_rp_rx_n[2]" +set_location_assignment PIN_BG5 -to "pcie_rp_rx_p[2]" +set_location_assignment PIN_BG1 -to "pcie_rp_tx_p[3]" +set_location_assignment PIN_BG2 -to "pcie_rp_tx_n[3]" +set_location_assignment PIN_BF8 -to "pcie_rp_rx_n[3]" +set_location_assignment PIN_BF7 -to "pcie_rp_rx_p[3]" +set_location_assignment PIN_BF3 -to "pcie_rp_tx_p[4]" +set_location_assignment PIN_BF4 -to "pcie_rp_tx_n[4]" +set_location_assignment PIN_BE6 -to "pcie_rp_rx_n[4]" +set_location_assignment PIN_BE5 -to "pcie_rp_rx_p[4]" +set_location_assignment PIN_BE1 -to "pcie_rp_tx_p[5]" +set_location_assignment PIN_BE2 -to "pcie_rp_tx_n[5]" +set_location_assignment PIN_BD8 -to "pcie_rp_rx_n[5]" +set_location_assignment PIN_BD7 -to "pcie_rp_rx_p[5]" +set_location_assignment PIN_BD3 -to "pcie_rp_tx_p[6]" +set_location_assignment PIN_BD4 -to "pcie_rp_tx_n[6]" +set_location_assignment PIN_BB8 -to "pcie_rp_rx_n[6]" +set_location_assignment PIN_BB7 -to "pcie_rp_rx_p[6]" +set_location_assignment PIN_BC1 -to "pcie_rp_tx_p[7]" +set_location_assignment PIN_BC2 -to "pcie_rp_tx_n[7]" +set_location_assignment PIN_BC5 -to "pcie_rp_rx_p[7]" +set_location_assignment PIN_BC6 -to "pcie_rp_rx_n[7]" +set_location_assignment PIN_BB3 -to "pcie_rp_tx_p[8]" +set_location_assignment PIN_BB4 -to "pcie_rp_tx_n[8]" +set_location_assignment PIN_BA5 -to "pcie_rp_rx_p[8]" +set_location_assignment PIN_BA6 -to "pcie_rp_rx_n[8]" +set_location_assignment PIN_BA1 -to "pcie_rp_tx_p[9]" +set_location_assignment PIN_BA2 -to "pcie_rp_tx_n[9]" +set_location_assignment PIN_AY7 -to "pcie_rp_rx_p[9]" +set_location_assignment PIN_AY8 -to "pcie_rp_rx_n[9]" +set_location_assignment PIN_AY3 -to "pcie_rp_tx_p[10]" +set_location_assignment PIN_AY4 -to "pcie_rp_tx_n[10]" +set_location_assignment PIN_AW5 -to "pcie_rp_rx_p[10]" +set_location_assignment PIN_AW6 -to "pcie_rp_rx_n[10]" +set_location_assignment PIN_AW1 -to "pcie_rp_tx_p[11]" +set_location_assignment PIN_AW2 -to "pcie_rp_tx_n[11]" +set_location_assignment PIN_AV7 -to "pcie_rp_rx_p[11]" +set_location_assignment PIN_AV8 -to "pcie_rp_rx_n[11]" +set_location_assignment PIN_AV3 -to "pcie_rp_tx_p[12]" +set_location_assignment PIN_AV4 -to "pcie_rp_tx_n[12]" +set_location_assignment PIN_AU5 -to "pcie_rp_rx_p[12]" +set_location_assignment PIN_AU6 -to "pcie_rp_rx_n[12]" +set_location_assignment PIN_AU1 -to "pcie_rp_tx_p[13]" +set_location_assignment PIN_AU2 -to "pcie_rp_tx_n[13]" +set_location_assignment PIN_AT7 -to "pcie_rp_rx_p[13]" +set_location_assignment PIN_AT8 -to "pcie_rp_rx_n[13]" +set_location_assignment PIN_AT3 -to "pcie_rp_tx_p[14]" +set_location_assignment PIN_AT4 -to "pcie_rp_tx_n[14]" +set_location_assignment PIN_AR5 -to "pcie_rp_rx_p[14]" +set_location_assignment PIN_AR6 -to "pcie_rp_rx_n[14]" +set_location_assignment PIN_AR1 -to "pcie_rp_tx_p[15]" +set_location_assignment PIN_AR2 -to "pcie_rp_tx_n[15]" +set_location_assignment PIN_AP7 -to "pcie_rp_rx_p[15]" +set_location_assignment PIN_AP8 -to "pcie_rp_rx_n[15]" + +set_location_assignment PIN_AW9 -to "refclk_pcie_rp_p" +set_location_assignment PIN_AW10 -to "refclk_pcie_rp_n" + +set_location_assignment PIN_BB17 -to "pcie_rp_s10_perstn" +set_location_assignment PIN_BG15 -to "pcie_rp_s10_waken" +set_location_assignment PIN_BG16 -to "pcie_rp_s10_prsnt2n" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_rp_tx_p[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "pcie_rp_rx_p[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_rp_tx_p[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "pcie_rp_rx_p[*]" + +set_instance_assignment -name IO_STANDARD "HCSL" -to "refclk_pcie_rp_p" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_rp_s10_perstn" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_rp_s10_waken" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "pcie_rp_s10_prsnt2n" + +# QSFP +set_location_assignment PIN_AN51 -to "qsfp0_tx_p[0]" +set_location_assignment PIN_AN50 -to "qsfp0_tx_n[0]" +set_location_assignment PIN_AM45 -to "qsfp0_rx_p[0]" +set_location_assignment PIN_AM44 -to "qsfp0_rx_n[0]" +set_location_assignment PIN_AL51 -to "qsfp0_tx_p[1]" +set_location_assignment PIN_AL50 -to "qsfp0_tx_n[1]" +set_location_assignment PIN_AK45 -to "qsfp0_rx_p[1]" +set_location_assignment PIN_AK44 -to "qsfp0_rx_n[1]" +set_location_assignment PIN_AG51 -to "qsfp0_tx_p[2]" +set_location_assignment PIN_AG50 -to "qsfp0_tx_n[2]" +set_location_assignment PIN_AF45 -to "qsfp0_rx_p[2]" +set_location_assignment PIN_AF44 -to "qsfp0_rx_n[2]" +set_location_assignment PIN_AJ51 -to "qsfp0_tx_p[3]" +set_location_assignment PIN_AJ50 -to "qsfp0_tx_n[3]" +set_location_assignment PIN_AH45 -to "qsfp0_rx_p[3]" +set_location_assignment PIN_AH44 -to "qsfp0_rx_n[3]" +set_location_assignment PIN_AJ43 -to "refclk_qsfp0_p" +set_location_assignment PIN_AJ42 -to "refclk_qsfp0_n" + +set_location_assignment PIN_AM3 -to "qsfp1_tx_p[0]" +set_location_assignment PIN_AM4 -to "qsfp1_tx_n[0]" +set_location_assignment PIN_AL5 -to "qsfp1_rx_p[0]" +set_location_assignment PIN_AL6 -to "qsfp1_rx_n[0]" +set_location_assignment PIN_AL1 -to "qsfp1_tx_p[1]" +set_location_assignment PIN_AL2 -to "qsfp1_tx_n[1]" +set_location_assignment PIN_AK7 -to "qsfp1_rx_p[1]" +set_location_assignment PIN_AK8 -to "qsfp1_rx_n[1]" +set_location_assignment PIN_AJ1 -to "qsfp1_tx_p[2]" +set_location_assignment PIN_AJ2 -to "qsfp1_tx_n[2]" +set_location_assignment PIN_AH7 -to "qsfp1_rx_p[2]" +set_location_assignment PIN_AH8 -to "qsfp1_rx_n[2]" +set_location_assignment PIN_AH3 -to "qsfp1_tx_p[3]" +set_location_assignment PIN_AH4 -to "qsfp1_tx_n[3]" +set_location_assignment PIN_AG5 -to "qsfp1_rx_p[3]" +set_location_assignment PIN_AG6 -to "qsfp1_rx_n[3]" +set_location_assignment PIN_AJ9 -to "refclk_qsfp1_p" +set_location_assignment PIN_AJ10 -to "refclk_qsfp1_n" + +set_location_assignment PIN_AW17 -to "qsfp0_modsel_l" +set_location_assignment PIN_AV16 -to "qsfp0_reset_l" +set_location_assignment PIN_AW16 -to "qsfp0_modprs_l" +set_location_assignment PIN_BC16 -to "qsfp0_lpmode" +set_location_assignment PIN_BB16 -to "qsfp0_int_l" + +set_location_assignment PIN_BA17 -to "qsfp1_modsel_l" +set_location_assignment PIN_AY16 -to "qsfp1_reset_l" +set_location_assignment PIN_AY15 -to "qsfp1_modprs_l" +set_location_assignment PIN_BE15 -to "qsfp1_lpmode" +set_location_assignment PIN_BF15 -to "qsfp1_int_l" + +set_location_assignment PIN_BD16 -to "qsfp_s10_i2c_sda" +set_location_assignment PIN_BJ16 -to "qsfp_s10_i2c_scl" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp0_tx_p[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp0_rx_p[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp0_tx_p[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp0_rx_p[*]" + +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp1_tx_p[*]" +set_instance_assignment -name IO_STANDARD "HSSI DIFFERENTIAL I/O" -to "qsfp1_rx_p[*]" + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp1_tx_p[*]" +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to "qsfp1_rx_p[*]" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp0_modsel_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp0_reset_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp0_modprs_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp0_lpmode" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp0_int_l" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp1_modsel_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp1_reset_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp1_modprs_l" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp1_lpmode" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp1_int_l" + +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp_s10_i2c_sda" +set_instance_assignment -name IO_STANDARD "1.8 V" -to "qsfp_s10_i2c_scl" + +set_instance_assignment -name IO_STANDARD "Differential LVPECL" -to "refclk_qsfp0_p" +set_instance_assignment -name IO_STANDARD "Differential LVPECL" -to "refclk_qsfp1_p" + +# DDR4 COMP +set_location_assignment PIN_A40 -to "ddr4_comp_rzq" + +set_location_assignment PIN_A38 -to "ddr4_comp_alert_n" +set_location_assignment PIN_F35 -to "ddr4_comp_reset_n" +set_location_assignment PIN_A39 -to "ddr4_comp_par" + +set_location_assignment PIN_H34 -to "ddr4_comp_a[0]" +set_location_assignment PIN_J34 -to "ddr4_comp_a[1]" +set_location_assignment PIN_G35 -to "ddr4_comp_a[2]" +set_location_assignment PIN_H35 -to "ddr4_comp_a[3]" +set_location_assignment PIN_L35 -to "ddr4_comp_a[4]" +set_location_assignment PIN_K35 -to "ddr4_comp_a[5]" +set_location_assignment PIN_L34 -to "ddr4_comp_a[6]" +set_location_assignment PIN_K34 -to "ddr4_comp_a[7]" +set_location_assignment PIN_N34 -to "ddr4_comp_a[8]" +set_location_assignment PIN_P34 -to "ddr4_comp_a[9]" +set_location_assignment PIN_M35 -to "ddr4_comp_a[10]" +set_location_assignment PIN_N35 -to "ddr4_comp_a[11]" +set_location_assignment PIN_B40 -to "ddr4_comp_a[12]" +set_location_assignment PIN_C39 -to "ddr4_comp_a[13]" +set_location_assignment PIN_D39 -to "ddr4_comp_a[14]" +set_location_assignment PIN_D38 -to "ddr4_comp_a[15]" +set_location_assignment PIN_C38 -to "ddr4_comp_a[16]" +set_location_assignment PIN_G37 -to "ddr4_comp_bg[0]" +set_location_assignment PIN_F34 -to "ddr4_comp_bg[1]" +set_location_assignment PIN_E35 -to "ddr4_comp_act_n" +set_location_assignment PIN_C36 -to "ddr4_comp_odt" +set_location_assignment PIN_B37 -to "ddr4_comp_clk_p" +set_location_assignment PIN_B38 -to "ddr4_comp_clk_n" +set_location_assignment PIN_E36 -to "ddr4_comp_cs_n" +set_location_assignment PIN_B36 -to "ddr4_comp_cke" +set_location_assignment PIN_D37 -to "ddr4_comp_ba[0]" +set_location_assignment PIN_F37 -to "ddr4_comp_ba[1]" + +set_location_assignment PIN_R34 -to "ddr4_comp_dbi_n[0]" +set_location_assignment PIN_J37 -to "ddr4_comp_dbi_n[1]" +set_location_assignment PIN_K39 -to "ddr4_comp_dbi_n[2]" +set_location_assignment PIN_F32 -to "ddr4_comp_dbi_n[3]" +set_location_assignment PIN_P31 -to "ddr4_comp_dbi_n[4]" +set_location_assignment PIN_N39 -to "ddr4_comp_dbi_n[5]" +set_location_assignment PIN_C41 -to "ddr4_comp_dbi_n[6]" +set_location_assignment PIN_M32 -to "ddr4_comp_dbi_n[7]" +set_location_assignment PIN_A33 -to "ddr4_comp_dbi_n[8]" + +set_location_assignment PIN_M36 -to "ddr4_comp_dqs_p[0]" +set_location_assignment PIN_N36 -to "ddr4_comp_dqs_n[0]" +set_location_assignment PIN_H38 -to "ddr4_comp_dqs_p[1]" +set_location_assignment PIN_J38 -to "ddr4_comp_dqs_n[1]" +set_location_assignment PIN_E42 -to "ddr4_comp_dqs_p[2]" +set_location_assignment PIN_F42 -to "ddr4_comp_dqs_n[2]" +set_location_assignment PIN_D32 -to "ddr4_comp_dqs_p[3]" +set_location_assignment PIN_E32 -to "ddr4_comp_dqs_n[3]" +set_location_assignment PIN_M31 -to "ddr4_comp_dqs_p[4]" +set_location_assignment PIN_N31 -to "ddr4_comp_dqs_n[4]" +set_location_assignment PIN_U37 -to "ddr4_comp_dqs_p[5]" +set_location_assignment PIN_T37 -to "ddr4_comp_dqs_n[5]" +set_location_assignment PIN_E41 -to "ddr4_comp_dqs_p[6]" +set_location_assignment PIN_E40 -to "ddr4_comp_dqs_n[6]" +set_location_assignment PIN_G33 -to "ddr4_comp_dqs_p[7]" +set_location_assignment PIN_F33 -to "ddr4_comp_dqs_n[7]" +set_location_assignment PIN_B31 -to "ddr4_comp_dqs_p[8]" +set_location_assignment PIN_A32 -to "ddr4_comp_dqs_n[8]" + +set_location_assignment PIN_K36 -to "ddr4_comp_dq[0]" +set_location_assignment PIN_H36 -to "ddr4_comp_dq[1]" +set_location_assignment PIN_P36 -to "ddr4_comp_dq[2]" +set_location_assignment PIN_T35 -to "ddr4_comp_dq[3]" +set_location_assignment PIN_J36 -to "ddr4_comp_dq[4]" +set_location_assignment PIN_G36 -to "ddr4_comp_dq[5]" +set_location_assignment PIN_R36 -to "ddr4_comp_dq[6]" +set_location_assignment PIN_T34 -to "ddr4_comp_dq[7]" +set_location_assignment PIN_K37 -to "ddr4_comp_dq[8]" +set_location_assignment PIN_G38 -to "ddr4_comp_dq[9]" +set_location_assignment PIN_M37 -to "ddr4_comp_dq[10]" +set_location_assignment PIN_P38 -to "ddr4_comp_dq[11]" +set_location_assignment PIN_L37 -to "ddr4_comp_dq[12]" +set_location_assignment PIN_P37 -to "ddr4_comp_dq[13]" +set_location_assignment PIN_N38 -to "ddr4_comp_dq[14]" +set_location_assignment PIN_R37 -to "ddr4_comp_dq[15]" +set_location_assignment PIN_G42 -to "ddr4_comp_dq[16]" +set_location_assignment PIN_J39 -to "ddr4_comp_dq[17]" +set_location_assignment PIN_H42 -to "ddr4_comp_dq[18]" +set_location_assignment PIN_G40 -to "ddr4_comp_dq[19]" +set_location_assignment PIN_H41 -to "ddr4_comp_dq[20]" +set_location_assignment PIN_L39 -to "ddr4_comp_dq[21]" +set_location_assignment PIN_H40 -to "ddr4_comp_dq[22]" +set_location_assignment PIN_G41 -to "ddr4_comp_dq[23]" +set_location_assignment PIN_B32 -to "ddr4_comp_dq[24]" +set_location_assignment PIN_G32 -to "ddr4_comp_dq[25]" +set_location_assignment PIN_C33 -to "ddr4_comp_dq[26]" +set_location_assignment PIN_J31 -to "ddr4_comp_dq[27]" +set_location_assignment PIN_B33 -to "ddr4_comp_dq[28]" +set_location_assignment PIN_H31 -to "ddr4_comp_dq[29]" +set_location_assignment PIN_D33 -to "ddr4_comp_dq[30]" +set_location_assignment PIN_K31 -to "ddr4_comp_dq[31]" +set_location_assignment PIN_M33 -to "ddr4_comp_dq[32]" +set_location_assignment PIN_R31 -to "ddr4_comp_dq[33]" +set_location_assignment PIN_N33 -to "ddr4_comp_dq[34]" +set_location_assignment PIN_R32 -to "ddr4_comp_dq[35]" +set_location_assignment PIN_L33 -to "ddr4_comp_dq[36]" +set_location_assignment PIN_T32 -to "ddr4_comp_dq[37]" +set_location_assignment PIN_P33 -to "ddr4_comp_dq[38]" +set_location_assignment PIN_T33 -to "ddr4_comp_dq[39]" +set_location_assignment PIN_P39 -to "ddr4_comp_dq[40]" +set_location_assignment PIN_T39 -to "ddr4_comp_dq[41]" +set_location_assignment PIN_T38 -to "ddr4_comp_dq[42]" +set_location_assignment PIN_V39 -to "ddr4_comp_dq[43]" +set_location_assignment PIN_M38 -to "ddr4_comp_dq[44]" +set_location_assignment PIN_V38 -to "ddr4_comp_dq[45]" +set_location_assignment PIN_U38 -to "ddr4_comp_dq[46]" +set_location_assignment PIN_W39 -to "ddr4_comp_dq[47]" +set_location_assignment PIN_C40 -to "ddr4_comp_dq[48]" +set_location_assignment PIN_E39 -to "ddr4_comp_dq[49]" +set_location_assignment PIN_B42 -to "ddr4_comp_dq[50]" +set_location_assignment PIN_F39 -to "ddr4_comp_dq[51]" +set_location_assignment PIN_D41 -to "ddr4_comp_dq[52]" +set_location_assignment PIN_F38 -to "ddr4_comp_dq[53]" +set_location_assignment PIN_D42 -to "ddr4_comp_dq[54]" +set_location_assignment PIN_F40 -to "ddr4_comp_dq[55]" +set_location_assignment PIN_C34 -to "ddr4_comp_dq[56]" +set_location_assignment PIN_H33 -to "ddr4_comp_dq[57]" +set_location_assignment PIN_D34 -to "ddr4_comp_dq[58]" +set_location_assignment PIN_J32 -to "ddr4_comp_dq[59]" +set_location_assignment PIN_C35 -to "ddr4_comp_dq[60]" +set_location_assignment PIN_J33 -to "ddr4_comp_dq[61]" +set_location_assignment PIN_E34 -to "ddr4_comp_dq[62]" +set_location_assignment PIN_L32 -to "ddr4_comp_dq[63]" +set_location_assignment PIN_C31 -to "ddr4_comp_dq[64]" +set_location_assignment PIN_C30 -to "ddr4_comp_dq[65]" +set_location_assignment PIN_A34 -to "ddr4_comp_dq[66]" +set_location_assignment PIN_A30 -to "ddr4_comp_dq[67]" +set_location_assignment PIN_D31 -to "ddr4_comp_dq[68]" +set_location_assignment PIN_E31 -to "ddr4_comp_dq[69]" +set_location_assignment PIN_B35 -to "ddr4_comp_dq[70]" +set_location_assignment PIN_B30 -to "ddr4_comp_dq[71]" + +# DDR4 DIMM CH0 +set_location_assignment PIN_B17 -to "ddr4_dimm_rzq" + +set_location_assignment PIN_M30 -to "ddr4_dimm_event_n" +set_location_assignment PIN_F30 -to "ddr4_dimm_save_n" +set_location_assignment PIN_C21 -to "ddr4_dimm_alert_n" +set_location_assignment PIN_P17 -to "ddr4_dimm_reset_n" +set_location_assignment PIN_H18 -to "ddr4_dimm_par" + +set_location_assignment PIN_J19 -to "ddr4_dimm_a[0]" +set_location_assignment PIN_H19 -to "ddr4_dimm_a[1]" +set_location_assignment PIN_L19 -to "ddr4_dimm_a[2]" +set_location_assignment PIN_K19 -to "ddr4_dimm_a[3]" +set_location_assignment PIN_G18 -to "ddr4_dimm_a[4]" +set_location_assignment PIN_F18 -to "ddr4_dimm_a[5]" +set_location_assignment PIN_G17 -to "ddr4_dimm_a[6]" +set_location_assignment PIN_F17 -to "ddr4_dimm_a[7]" +set_location_assignment PIN_E17 -to "ddr4_dimm_a[8]" +set_location_assignment PIN_E16 -to "ddr4_dimm_a[9]" +set_location_assignment PIN_D17 -to "ddr4_dimm_a[10]" +set_location_assignment PIN_D18 -to "ddr4_dimm_a[11]" +set_location_assignment PIN_A17 -to "ddr4_dimm_a[12]" +set_location_assignment PIN_E19 -to "ddr4_dimm_a[13]" +set_location_assignment PIN_F19 -to "ddr4_dimm_a[14]" +set_location_assignment PIN_C19 -to "ddr4_dimm_a[15]" +set_location_assignment PIN_D19 -to "ddr4_dimm_a[16]" +set_location_assignment PIN_A20 -to "ddr4_dimm_a[17]" +set_location_assignment PIN_A19 -to "ddr4_dimm_bg[0]" +set_location_assignment PIN_R17 -to "ddr4_dimm_bg[1]" +set_location_assignment PIN_N18 -to "ddr4_dimm_act_n" +set_location_assignment PIN_M18 -to "ddr4_dimm_odt[0]" +set_location_assignment PIN_L18 -to "ddr4_dimm_odt[1]" +set_location_assignment PIN_K17 -to "ddr4_dimm_ck_p[0]" +set_location_assignment PIN_J17 -to "ddr4_dimm_ck_n[0]" +set_location_assignment PIN_D22 -to "ddr4_dimm_ck_p[1]" +set_location_assignment PIN_E22 -to "ddr4_dimm_ck_n[1]" +set_location_assignment PIN_P18 -to "ddr4_dimm_cs_n[0]" +set_location_assignment PIN_J18 -to "ddr4_dimm_cs_n[1]" +set_location_assignment PIN_E20 -to "ddr4_dimm_cs_n[2]" +set_location_assignment PIN_F20 -to "ddr4_dimm_cs_n[3]" +set_location_assignment PIN_G20 -to "ddr4_dimm_c2" +set_location_assignment PIN_M17 -to "ddr4_dimm_cke[0]" +set_location_assignment PIN_L17 -to "ddr4_dimm_cke[1]" +set_location_assignment PIN_B20 -to "ddr4_dimm_ba[0]" +set_location_assignment PIN_A18 -to "ddr4_dimm_ba[1]" + +set_location_assignment PIN_L14 -to "ddr4_dimm_dqs_p[0]" +set_location_assignment PIN_K14 -to "ddr4_dimm_dqs_n[0]" +set_location_assignment PIN_M15 -to "ddr4_dimm_dqs_p[1]" +set_location_assignment PIN_N15 -to "ddr4_dimm_dqs_n[1]" +set_location_assignment PIN_L20 -to "ddr4_dimm_dqs_p[2]" +set_location_assignment PIN_K20 -to "ddr4_dimm_dqs_n[2]" +set_location_assignment PIN_E10 -to "ddr4_dimm_dqs_p[3]" +set_location_assignment PIN_E11 -to "ddr4_dimm_dqs_n[3]" +set_location_assignment PIN_A14 -to "ddr4_dimm_dqs_p[4]" +set_location_assignment PIN_A15 -to "ddr4_dimm_dqs_n[4]" +set_location_assignment PIN_F27 -to "ddr4_dimm_dqs_p[5]" +set_location_assignment PIN_E27 -to "ddr4_dimm_dqs_n[5]" +set_location_assignment PIN_D24 -to "ddr4_dimm_dqs_p[6]" +set_location_assignment PIN_C24 -to "ddr4_dimm_dqs_n[6]" +set_location_assignment PIN_B22 -to "ddr4_dimm_dqs_p[7]" +set_location_assignment PIN_B21 -to "ddr4_dimm_dqs_n[7]" +set_location_assignment PIN_B12 -to "ddr4_dimm_dqs_p[8]" +set_location_assignment PIN_B11 -to "ddr4_dimm_dqs_n[8]" +set_location_assignment PIN_F13 -to "ddr4_dimm_dqs_p[9]" +set_location_assignment PIN_F14 -to "ddr4_dimm_dqs_n[9]" +set_location_assignment PIN_J16 -to "ddr4_dimm_dqs_p[10]" +set_location_assignment PIN_K16 -to "ddr4_dimm_dqs_n[10]" +set_location_assignment PIN_N19 -to "ddr4_dimm_dqs_p[11]" +set_location_assignment PIN_P19 -to "ddr4_dimm_dqs_n[11]" +set_location_assignment PIN_C10 -to "ddr4_dimm_dqs_p[12]" +set_location_assignment PIN_B10 -to "ddr4_dimm_dqs_n[12]" +set_location_assignment PIN_B15 -to "ddr4_dimm_dqs_p[13]" +set_location_assignment PIN_B16 -to "ddr4_dimm_dqs_n[13]" +set_location_assignment PIN_J26 -to "ddr4_dimm_dqs_p[14]" +set_location_assignment PIN_H26 -to "ddr4_dimm_dqs_n[14]" +set_location_assignment PIN_J24 -to "ddr4_dimm_dqs_p[15]" +set_location_assignment PIN_H24 -to "ddr4_dimm_dqs_n[15]" +set_location_assignment PIN_G23 -to "ddr4_dimm_dqs_p[16]" +set_location_assignment PIN_F23 -to "ddr4_dimm_dqs_n[16]" +set_location_assignment PIN_D14 -to "ddr4_dimm_dqs_p[17]" +set_location_assignment PIN_E14 -to "ddr4_dimm_dqs_n[17]" + +set_location_assignment PIN_T14 -to "ddr4_dimm_dq[0]" +set_location_assignment PIN_R14 -to "ddr4_dimm_dq[1]" +set_location_assignment PIN_N14 -to "ddr4_dimm_dq[2]" +set_location_assignment PIN_H14 -to "ddr4_dimm_dq[3]" +set_location_assignment PIN_T15 -to "ddr4_dimm_dq[4]" +set_location_assignment PIN_R15 -to "ddr4_dimm_dq[5]" +set_location_assignment PIN_P14 -to "ddr4_dimm_dq[6]" +set_location_assignment PIN_J14 -to "ddr4_dimm_dq[7]" +set_location_assignment PIN_N16 -to "ddr4_dimm_dq[8]" +set_location_assignment PIN_M16 -to "ddr4_dimm_dq[9]" +set_location_assignment PIN_H16 -to "ddr4_dimm_dq[10]" +set_location_assignment PIN_G16 -to "ddr4_dimm_dq[11]" +set_location_assignment PIN_R16 -to "ddr4_dimm_dq[12]" +set_location_assignment PIN_P16 -to "ddr4_dimm_dq[13]" +set_location_assignment PIN_L15 -to "ddr4_dimm_dq[14]" +set_location_assignment PIN_K15 -to "ddr4_dimm_dq[15]" +set_location_assignment PIN_K21 -to "ddr4_dimm_dq[16]" +set_location_assignment PIN_J22 -to "ddr4_dimm_dq[17]" +set_location_assignment PIN_M20 -to "ddr4_dimm_dq[18]" +set_location_assignment PIN_K22 -to "ddr4_dimm_dq[19]" +set_location_assignment PIN_J23 -to "ddr4_dimm_dq[20]" +set_location_assignment PIN_H23 -to "ddr4_dimm_dq[21]" +set_location_assignment PIN_N20 -to "ddr4_dimm_dq[22]" +set_location_assignment PIN_J21 -to "ddr4_dimm_dq[23]" +set_location_assignment PIN_H10 -to "ddr4_dimm_dq[24]" +set_location_assignment PIN_A10 -to "ddr4_dimm_dq[25]" +set_location_assignment PIN_G10 -to "ddr4_dimm_dq[26]" +set_location_assignment PIN_C11 -to "ddr4_dimm_dq[27]" +set_location_assignment PIN_F10 -to "ddr4_dimm_dq[28]" +set_location_assignment PIN_A9 -to "ddr4_dimm_dq[29]" +set_location_assignment PIN_H11 -to "ddr4_dimm_dq[30]" +set_location_assignment PIN_D11 -to "ddr4_dimm_dq[31]" +set_location_assignment PIN_C14 -to "ddr4_dimm_dq[32]" +set_location_assignment PIN_C16 -to "ddr4_dimm_dq[33]" +set_location_assignment PIN_F15 -to "ddr4_dimm_dq[34]" +set_location_assignment PIN_E15 -to "ddr4_dimm_dq[35]" +set_location_assignment PIN_G15 -to "ddr4_dimm_dq[36]" +set_location_assignment PIN_C15 -to "ddr4_dimm_dq[37]" +set_location_assignment PIN_D16 -to "ddr4_dimm_dq[38]" +set_location_assignment PIN_H15 -to "ddr4_dimm_dq[39]" +set_location_assignment PIN_C26 -to "ddr4_dimm_dq[40]" +set_location_assignment PIN_C25 -to "ddr4_dimm_dq[41]" +set_location_assignment PIN_B27 -to "ddr4_dimm_dq[42]" +set_location_assignment PIN_G26 -to "ddr4_dimm_dq[43]" +set_location_assignment PIN_E26 -to "ddr4_dimm_dq[44]" +set_location_assignment PIN_D26 -to "ddr4_dimm_dq[45]" +set_location_assignment PIN_B26 -to "ddr4_dimm_dq[46]" +set_location_assignment PIN_G27 -to "ddr4_dimm_dq[47]" +set_location_assignment PIN_B25 -to "ddr4_dimm_dq[48]" +set_location_assignment PIN_F24 -to "ddr4_dimm_dq[49]" +set_location_assignment PIN_F25 -to "ddr4_dimm_dq[50]" +set_location_assignment PIN_H25 -to "ddr4_dimm_dq[51]" +set_location_assignment PIN_A25 -to "ddr4_dimm_dq[52]" +set_location_assignment PIN_E24 -to "ddr4_dimm_dq[53]" +set_location_assignment PIN_E25 -to "ddr4_dimm_dq[54]" +set_location_assignment PIN_G25 -to "ddr4_dimm_dq[55]" +set_location_assignment PIN_A22 -to "ddr4_dimm_dq[56]" +set_location_assignment PIN_F22 -to "ddr4_dimm_dq[57]" +set_location_assignment PIN_A24 -to "ddr4_dimm_dq[58]" +set_location_assignment PIN_B23 -to "ddr4_dimm_dq[59]" +set_location_assignment PIN_C23 -to "ddr4_dimm_dq[60]" +set_location_assignment PIN_G22 -to "ddr4_dimm_dq[61]" +set_location_assignment PIN_A23 -to "ddr4_dimm_dq[62]" +set_location_assignment PIN_D23 -to "ddr4_dimm_dq[63]" +set_location_assignment PIN_D12 -to "ddr4_dimm_dq[64]" +set_location_assignment PIN_E12 -to "ddr4_dimm_dq[65]" +set_location_assignment PIN_A12 -to "ddr4_dimm_dq[66]" +set_location_assignment PIN_A13 -to "ddr4_dimm_dq[67]" +set_location_assignment PIN_D13 -to "ddr4_dimm_dq[68]" +set_location_assignment PIN_F12 -to "ddr4_dimm_dq[69]" +set_location_assignment PIN_C13 -to "ddr4_dimm_dq[70]" +set_location_assignment PIN_B13 -to "ddr4_dimm_dq[71]" diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.sdc b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.sdc new file mode 100644 index 000000000..299e58dc9 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga.sdc @@ -0,0 +1,102 @@ +# Timing constraints for the Intel Stratix 10 MX FPGA development board + +set_time_format -unit ns -decimal_places 3 + +# Clock constraints +create_clock -period 20.000 -name {clk_sys_50m} [ get_ports {clk_sys_50m_p} ] +create_clock -period 10.000 -name {clk_sys_100m} [ get_ports {clk_sys_100m_p} ] +create_clock -period 10.000 -name {clk_core_bak} [ get_ports {clk_core_bak_p} ] +create_clock -period 10.000 -name {clk_uib0} [ get_ports {clk_uib0_p} ] +create_clock -period 10.000 -name {clk_uib1} [ get_ports {clk_uib1_p} ] +create_clock -period 10.000 -name {clk_esram0} [ get_ports {clk_esram0_p} ] +create_clock -period 10.000 -name {clk_esram1} [ get_ports {clk_esram1_p} ] +create_clock -period 7.500 -name {clk_ddr4_comp} [ get_ports {clk_ddr4_comp_p} ] +create_clock -period 7.500 -name {clk_ddr4_dimm} [ get_ports {clk_ddr4_dimm_p} ] + +create_clock -period 10.000 -name {refclk_pcie_ep} [ get_ports {refclk_pcie_ep_p} ] +create_clock -period 10.000 -name {refclk_pcie_ep_edge} [ get_ports {refclk_pcie_ep_edge_p} ] +create_clock -period 10.000 -name {refclk_pcie_ep1} [ get_ports {refclk_pcie_ep1_p} ] +create_clock -period 10.000 -name {refclk_pcie_rp} [ get_ports {refclk_pcie_rp_p} ] + +create_clock -period 1.551 -name {refclk_qsfp0} [ get_ports {refclk_qsfp0_p} ] +create_clock -period 1.551 -name {refclk_qsfp1} [ get_ports {refclk_qsfp1_p} ] + +derive_clock_uncertainty + +set_clock_groups -asynchronous -group [ get_clocks {clk_sys_50m} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_sys_100m} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_core_bak} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_uib0} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_uib1} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_esram0} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_esram1} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_ddr4_comp} ] +set_clock_groups -asynchronous -group [ get_clocks {clk_ddr4_dimm} ] + +set_clock_groups -asynchronous -group [ get_clocks {refclk_pcie_ep} ] +set_clock_groups -asynchronous -group [ get_clocks {refclk_pcie_ep_edge} ] +set_clock_groups -asynchronous -group [ get_clocks {refclk_pcie_ep1} ] +set_clock_groups -asynchronous -group [ get_clocks {refclk_pcie_rp} ] + +set_clock_groups -asynchronous -group [ get_clocks {refclk_qsfp0} ] +set_clock_groups -asynchronous -group [ get_clocks {refclk_qsfp1} ] + +# JTAG constraints +create_clock -name {altera_reserved_tck} -period 40.800 {altera_reserved_tck} + +set_clock_groups -asynchronous -group [get_clocks {altera_reserved_tck}] + +# IO constraints +set_false_path -from "cpu_resetn" +set_false_path -to "user_led[*]" + +set_false_path -from "s10_pcie_perstn0" +set_false_path -from "s10_pcie_perstn1" + +# source ../lib/eth/syn/quartus_pro/eth_mac_fifo.sdc +# source ../lib/eth/lib/axis/syn/quartus_pro/sync_reset.sdc +# source ../lib/eth/lib/axis/syn/quartus_pro/axis_async_fifo.sdc + +# # clocking infrastructure +# constrain_sync_reset_inst "sync_reset_100mhz_inst" + +# # PHY clocks +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_1|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_1|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_2|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_2|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_3|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_3|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_4|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_4|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_1|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_1|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_2|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_2|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_3|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_3|eth_xcvr_inst|rx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|eth_xcvr_inst|tx_clkout|ch0} ] +# set_clock_groups -asynchronous -group [ get_clocks {qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|eth_xcvr_inst|rx_clkout|ch0} ] + +# # PHY resets +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_1|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_1|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_2|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_2|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_3|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_3|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp0_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_1|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_1|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_2|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_2|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_3|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_3|phy_rx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_tx_rst_reset_sync_inst" +# constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_rx_rst_reset_sync_inst" + +# # 10G MAC +# constrain_eth_mac_fifo_inst "core_inst|eth_mac_10g_fifo_inst" +# constrain_axis_async_fifo_inst "core_inst|eth_mac_10g_fifo_inst|rx_fifo|fifo_inst" +# constrain_axis_async_fifo_inst "core_inst|eth_mac_10g_fifo_inst|tx_fifo|fifo_inst" diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21b/Makefile b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21b/Makefile new file mode 100644 index 000000000..68df6f3f6 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21b/Makefile @@ -0,0 +1,49 @@ + +# FPGA settings +FPGA_TOP = fpga +FPGA_FAMILY = "Stratix 10 MX" +FPGA_DEVICE = 1SM21BHU2F53E1VG + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/common/example_core_pcie_s10.v +SYN_FILES += rtl/common/example_core_pcie.v +SYN_FILES += rtl/common/example_core.v +SYN_FILES += rtl/common/axi_ram.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_rx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_tx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_cfg.v +SYN_FILES += lib/pcie/rtl/pcie_s10_msi.v +SYN_FILES += lib/pcie/rtl/pcie_axil_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v +SYN_FILES += lib/pcie/rtl/dma_psdpram.v +SYN_FILES += lib/pcie/rtl/arbiter.v +SYN_FILES += lib/pcie/rtl/priority_encoder.v +SYN_FILES += lib/pcie/rtl/pulse_merge.v + +# IP files +IP_TCL_FILES += ip/reset_release.tcl +IP_TCL_FILES += ip/pcie.tcl + +# QSF files +QSF_FILES = fpga.qsf + +# SDC files +SDC_FILES = fpga.sdc + +include ../common/quartus_pro.mk + +program: fpga + quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof@1" diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21c/Makefile b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21c/Makefile new file mode 100644 index 000000000..cfbc88771 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/fpga_1sm21c/Makefile @@ -0,0 +1,49 @@ + +# FPGA settings +FPGA_TOP = fpga +FPGA_FAMILY = "Stratix 10 MX" +FPGA_DEVICE = 1SM21CHU1F53E1VG + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/common/example_core_pcie_s10.v +SYN_FILES += rtl/common/example_core_pcie.v +SYN_FILES += rtl/common/example_core.v +SYN_FILES += rtl/common/axi_ram.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_rx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_if_tx.v +SYN_FILES += lib/pcie/rtl/pcie_s10_cfg.v +SYN_FILES += lib/pcie/rtl/pcie_s10_msi.v +SYN_FILES += lib/pcie/rtl/pcie_axil_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v +SYN_FILES += lib/pcie/rtl/dma_psdpram.v +SYN_FILES += lib/pcie/rtl/arbiter.v +SYN_FILES += lib/pcie/rtl/priority_encoder.v +SYN_FILES += lib/pcie/rtl/pulse_merge.v + +# IP files +IP_TCL_FILES += ip/reset_release.tcl +IP_TCL_FILES += ip/pcie.tcl + +# QSF files +QSF_FILES = fpga.qsf + +# SDC files +SDC_FILES = fpga.sdc + +include ../common/quartus_pro.mk + +program: fpga + quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof@1" diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/ip/pcie.tcl b/fpga/lib/pcie/example/S10MX_DK/fpga/ip/pcie.tcl new file mode 100644 index 000000000..fc304732a --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/ip/pcie.tcl @@ -0,0 +1,350 @@ +package require -exact qsys 21.3 + +# create the system "pcie" +proc do_create_pcie {} { + # create the system + create_system pcie + set_project_property DEVICE {1SM21CHU1F53E1VG} + set_project_property DEVICE_FAMILY {Stratix 10} + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance pcie_s10_hip_ast_0 altera_pcie_s10_hip_ast + set_instance_parameter_value pcie_s10_hip_ast_0 {anlg_voltage} {1_1V} + set_instance_parameter_value pcie_s10_hip_ast_0 {apps_type_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_clk_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_control_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_npor_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {bfm_drive_interface_pipe_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {ceb_extend_pcie_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {chosen_devkit_hwtcl} {Stratix 10 MX H-Tile Production FPGA Development Kit} + set_instance_parameter_value pcie_s10_hip_ast_0 {cvp_user_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {design_environment} {NATIVE} + set_instance_parameter_value pcie_s10_hip_ast_0 {device_ctrl_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {disable_256_to_512_adapter_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {eios_workaround_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_avst_reset_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_qii_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_sim_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_sim_rp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_synth_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_synth_rp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_example_design_tb_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_multi_func_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pcie_cv_fix} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pipe32_phyip_ser_driver_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_pld_warm_rst_rdy_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_rx_buffer_limit_ports_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_sriov_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {enable_test_out_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {hip_reconfig_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {hrc_rstctl_timer_g_delay_added_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {msi_info_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pcie_link_inspector_avmm_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pcie_link_inspector_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_auto_lane_flip_ctrl_en_hwtcl} {enable} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar0_address_width_hwtcl} {24} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar0_type_hwtcl} {64-bit prefetchable memory} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar2_address_width_hwtcl} {24} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar2_type_hwtcl} {64-bit prefetchable memory} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_eq_eieos_cnt_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_loopback_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msi_multiple_msg_cap_hwtcl} {32} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_type0_device_id_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pci_type0_vendor_id_hwtcl} {4660} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ep_l0s_accpt_latency_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ep_l1_accpt_latency_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_ext_tag_supp_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_flr_cap_user_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_phy_slot_num_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_port_num_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_sel_deemphasis_hwtcl} {6dB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_clk_config_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_power_limit_scale_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_cap_slot_power_limit_value_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_pcie_slot_imp_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_revision_id_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_subsys_dev_id_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_subsys_vendor_id_hwtcl} {4466} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf0_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf1_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf2_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_class_code_hwtcl} {16711680} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_expansion_base_address_register_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msi_multiple_msg_cap_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_bir_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_pba_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_pba_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_offset_hwtcl} {0.0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_msix_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_type0_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_pci_type0_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_revision_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_sup_page_size_user_hwtcl} {4KB, 8KB, 64KB, 256KB, 1MB, 4MB} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar0_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar0_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar1_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar1_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar2_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar2_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar3_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar3_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar4_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar4_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar5_address_width_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_bar5_type_hwtcl} {Disabled} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_sriov_vf_device_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_subsys_dev_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_subsys_vendor_id_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_loc_1_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_loc_1_vfcomm_cs2_hwtcl} {ST table not present} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_size_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_req_cap_st_table_size_vfcomm_cs2_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_count_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_st_dev_spec_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pf3_vf_tph_st_int_mode_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {pll_refclk_freq_hwtcl} {100 MHz} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_design_example_hwtcl} {PIO} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_design_example_rtl_lang_hwtcl} {Verilog} + set_instance_parameter_value pcie_s10_hip_ast_0 {select_example_design_sim_BFM_hwtcl} {Intel FPGA BFM} + set_instance_parameter_value pcie_s10_hip_ast_0 {serial_sim_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {targeted_devkit_hwtcl} {NONE} + set_instance_parameter_value pcie_s10_hip_ast_0 {total_pf_count_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_ast_parity_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_pll_lock_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {use_rpbfm_pro} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_ep_native_hwtcl} {Native} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_maxpayload_size_hwtcl} {1024} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_msi_enable_hwtcl} {1} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf0_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf1_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf2_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_ats_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_msi_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_msix_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_pf3_tph_cap_enable_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {virtual_rp_ep_mode_hwtcl} {Native Endpoint} + set_instance_parameter_value pcie_s10_hip_ast_0 {wrala_hwtcl} {Gen3x8, Interface - 256 bit, 250 MHz} + set_instance_parameter_value pcie_s10_hip_ast_0 {xcvr_adme_hwtcl} {0} + set_instance_parameter_value pcie_s10_hip_ast_0 {xcvr_reconfig_hwtcl} {0} + set_instance_property pcie_s10_hip_ast_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property refclk EXPORT_OF pcie_s10_hip_ast_0.refclk + set_interface_property coreclkout_hip EXPORT_OF pcie_s10_hip_ast_0.coreclkout_hip + set_interface_property npor EXPORT_OF pcie_s10_hip_ast_0.npor + set_interface_property hip_rst EXPORT_OF pcie_s10_hip_ast_0.hip_rst + set_interface_property clr_st EXPORT_OF pcie_s10_hip_ast_0.clr_st + set_interface_property ninit_done EXPORT_OF pcie_s10_hip_ast_0.ninit_done + set_interface_property rx_st EXPORT_OF pcie_s10_hip_ast_0.rx_st + set_interface_property tx_st EXPORT_OF pcie_s10_hip_ast_0.tx_st + set_interface_property rx_bar EXPORT_OF pcie_s10_hip_ast_0.rx_bar + set_interface_property tx_cred EXPORT_OF pcie_s10_hip_ast_0.tx_cred + set_interface_property int_msi EXPORT_OF pcie_s10_hip_ast_0.int_msi + set_interface_property hip_status EXPORT_OF pcie_s10_hip_ast_0.hip_status + set_interface_property config_tl EXPORT_OF pcie_s10_hip_ast_0.config_tl + set_interface_property hip_ctrl EXPORT_OF pcie_s10_hip_ast_0.hip_ctrl + set_interface_property currentspeed EXPORT_OF pcie_s10_hip_ast_0.currentspeed + set_interface_property hip_pipe EXPORT_OF pcie_s10_hip_ast_0.hip_pipe + set_interface_property hip_serial EXPORT_OF pcie_s10_hip_ast_0.hip_serial + set_interface_property power_mgnt EXPORT_OF pcie_s10_hip_ast_0.power_mgnt + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {pcie.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {pcie} + + # save the system + sync_sysinfo_parameters + save_system pcie +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_pcie + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/ip/reset_release.tcl b/fpga/lib/pcie/example/S10MX_DK/fpga/ip/reset_release.tcl new file mode 100644 index 000000000..d4c02386d --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/ip/reset_release.tcl @@ -0,0 +1,50 @@ +package require -exact qsys 20.4 + +# create the system "reset_release" +proc do_create_reset_release {} { + # create the system + create_system reset_release + set_project_property DEVICE {1SM21CHU1F53E1VG} + set_project_property DEVICE_FAMILY {Stratix 10} + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance s10_user_rst_clkgate_0 altera_s10_user_rst_clkgate + set_instance_parameter_value s10_user_rst_clkgate_0 {outputType} {Conduit Interface} + set_instance_property s10_user_rst_clkgate_0 AUTO_EXPORT true + + # add wirelevel expressions + + # add the exports + set_interface_property ninit_done EXPORT_OF s10_user_rst_clkgate_0.ninit_done + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {reset_release.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {reset_release} + + # save the system + sync_sysinfo_parameters + save_system reset_release +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_reset_release + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/lib/pcie b/fpga/lib/pcie/example/S10MX_DK/fpga/lib/pcie new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/lib/pcie @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/common b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/common new file mode 120000 index 000000000..543afe472 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/common @@ -0,0 +1 @@ +../lib/pcie/example/common/rtl/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/debounce_switch.v b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..8e93a50c4 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/debounce_switch.v @@ -0,0 +1,93 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga.v b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga.v new file mode 100644 index 000000000..51e90cc31 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga.v @@ -0,0 +1,519 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 100 MHz + * Reset: Push button, active low + */ + input wire clk_sys_100m_p, + input wire cpu_resetn, + + /* + * GPIO + */ + output wire [3:0] user_led, + + /* + * PCIe: gen 3 x16 + */ + output wire [7:0] pcie_ep_rx_p, + input wire [7:0] pcie_ep_tx_p, + input wire refclk_pcie_ep_edge_p, + input wire s10_pcie_perstn0 +); + +parameter SEG_COUNT = 1; +parameter SEG_DATA_WIDTH = 256; +parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32); + +parameter TX_SEQ_NUM_WIDTH = 6; + +parameter PCIE_TAG_COUNT = 256; +parameter BAR0_APERTURE = 24; +parameter BAR2_APERTURE = 24; + +// Clock and reset + +wire ninit_done; + +reset_release reset_release_inst ( + .ninit_done (ninit_done) +); + +wire clk_100mhz = clk_sys_100m_p; +wire rst_100mhz; + +sync_reset #( + .N(20) +) +sync_reset_100mhz_inst ( + .clk(clk_100mhz), + .rst(!cpu_resetn || ninit_done), + .out(rst_100mhz) +); + +wire coreclkout_hip; +wire reset_status; + +wire clk = coreclkout_hip; +wire rst = reset_status; + +wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data; +wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty; +wire [SEG_COUNT-1:0] rx_st_sop; +wire [SEG_COUNT-1:0] rx_st_eop; +wire [SEG_COUNT-1:0] rx_st_valid; +wire rx_st_ready; +wire [SEG_COUNT-1:0] rx_st_vf_active = 0; +wire [SEG_COUNT*3-1:0] rx_st_func_num = 0; +wire [SEG_COUNT*11-1:0] rx_st_vf_num = 0; +wire [SEG_COUNT*3-1:0] rx_st_bar_range; + +wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data; +wire [SEG_COUNT-1:0] tx_st_sop; +wire [SEG_COUNT-1:0] tx_st_eop; +wire [SEG_COUNT-1:0] tx_st_valid; +wire tx_st_ready; +wire [SEG_COUNT-1:0] tx_st_err; + +wire [7:0] tx_ph_cdts; +wire [11:0] tx_pd_cdts; +wire [7:0] tx_nph_cdts; +wire [11:0] tx_npd_cdts; +wire [7:0] tx_cplh_cdts; +wire [11:0] tx_cpld_cdts; +wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed; +wire [SEG_COUNT-1:0] tx_data_cdts_consumed; +wire [SEG_COUNT*2-1:0] tx_cdts_type; +wire [SEG_COUNT*1-1:0] tx_cdts_data_value; + +wire app_msi_req; +wire app_msi_ack; +wire [2:0] app_msi_tc; +wire [4:0] app_msi_num; +wire [1:0] app_msi_func_num; + +wire [31:0] tl_cfg_ctl; +wire [4:0] tl_cfg_add; +wire [1:0] tl_cfg_func; + +pcie pcie_hip_inst ( + .refclk (refclk_pcie_ep_edge_p), + .coreclkout_hip (coreclkout_hip), + .npor (!rst_100mhz), + .pin_perst (s10_pcie_perstn0), + .reset_status (reset_status), + .serdes_pll_locked (), + .pld_core_ready (1'b1), + .pld_clk_inuse (), + .testin_zero (), + .clr_st (), + .ninit_done (ninit_done), + .rx_st_ready (rx_st_ready), + .rx_st_sop (rx_st_sop), + .rx_st_eop (rx_st_eop), + .rx_st_data (rx_st_data), + .rx_st_valid (rx_st_valid), + .rx_st_empty (rx_st_empty), + .tx_st_sop (tx_st_sop), + .tx_st_eop (tx_st_eop), + .tx_st_data (tx_st_data), + .tx_st_valid (tx_st_valid), + .tx_st_err (tx_st_err), + .tx_st_ready (tx_st_ready), + .rx_st_bar_range (rx_st_bar_range), + .tx_cdts_type (tx_cdts_type), + .tx_data_cdts_consumed (tx_data_cdts_consumed), + .tx_hdr_cdts_consumed (tx_hdr_cdts_consumed), + .tx_cdts_data_value (tx_cdts_data_value), + .tx_cpld_cdts (tx_cpld_cdts), + .tx_pd_cdts (tx_pd_cdts), + .tx_npd_cdts (tx_npd_cdts), + .tx_cplh_cdts (tx_cplh_cdts), + .tx_ph_cdts (tx_ph_cdts), + .tx_nph_cdts (tx_nph_cdts), + .app_msi_req (app_msi_req), + .app_msi_ack (app_msi_ack), + .app_msi_tc (app_msi_tc), + .app_msi_num (app_msi_num), + .app_int_sts (4'd0), + .app_msi_func_num (app_msi_func_num), + .int_status (), + .int_status_common (), + .derr_cor_ext_rpl (), + .derr_rpl (), + .derr_cor_ext_rcv (), + .derr_uncor_ext_rcv (), + .rx_par_err (), + .tx_par_err (), + .ltssmstate (), + .link_up (), + .lane_act (), + .tl_cfg_func (tl_cfg_func), + .tl_cfg_add (tl_cfg_add), + .tl_cfg_ctl (tl_cfg_ctl), + .app_err_valid (0), + .app_err_hdr (0), + .app_err_info (0), + .app_err_func_num (0), + .test_in (0), + .simu_mode_pipe (0), + .currentspeed (), + .sim_pipe_pclk_in (1'b0), + .sim_pipe_rate (), + .sim_ltssmstate (), + .txdata0 (), + .txdata1 (), + .txdata2 (), + .txdata3 (), + .txdata4 (), + .txdata5 (), + .txdata6 (), + .txdata7 (), + .txdatak0 (), + .txdatak1 (), + .txdatak2 (), + .txdatak3 (), + .txdatak4 (), + .txdatak5 (), + .txdatak6 (), + .txdatak7 (), + .txcompl0 (), + .txcompl1 (), + .txcompl2 (), + .txcompl3 (), + .txcompl4 (), + .txcompl5 (), + .txcompl6 (), + .txcompl7 (), + .txelecidle0 (), + .txelecidle1 (), + .txelecidle2 (), + .txelecidle3 (), + .txelecidle4 (), + .txelecidle5 (), + .txelecidle6 (), + .txelecidle7 (), + .txdetectrx0 (), + .txdetectrx1 (), + .txdetectrx2 (), + .txdetectrx3 (), + .txdetectrx4 (), + .txdetectrx5 (), + .txdetectrx6 (), + .txdetectrx7 (), + .powerdown0 (), + .powerdown1 (), + .powerdown2 (), + .powerdown3 (), + .powerdown4 (), + .powerdown5 (), + .powerdown6 (), + .powerdown7 (), + .txmargin0 (), + .txmargin1 (), + .txmargin2 (), + .txmargin3 (), + .txmargin4 (), + .txmargin5 (), + .txmargin6 (), + .txmargin7 (), + .txdeemph0 (), + .txdeemph1 (), + .txdeemph2 (), + .txdeemph3 (), + .txdeemph4 (), + .txdeemph5 (), + .txdeemph6 (), + .txdeemph7 (), + .txswing0 (), + .txswing1 (), + .txswing2 (), + .txswing3 (), + .txswing4 (), + .txswing5 (), + .txswing6 (), + .txswing7 (), + .txsynchd0 (), + .txsynchd1 (), + .txsynchd2 (), + .txsynchd3 (), + .txsynchd4 (), + .txsynchd5 (), + .txsynchd6 (), + .txsynchd7 (), + .txblkst0 (), + .txblkst1 (), + .txblkst2 (), + .txblkst3 (), + .txblkst4 (), + .txblkst5 (), + .txblkst6 (), + .txblkst7 (), + .txdataskip0 (), + .txdataskip1 (), + .txdataskip2 (), + .txdataskip3 (), + .txdataskip4 (), + .txdataskip5 (), + .txdataskip6 (), + .txdataskip7 (), + .rate0 (), + .rate1 (), + .rate2 (), + .rate3 (), + .rate4 (), + .rate5 (), + .rate6 (), + .rate7 (), + .rxpolarity0 (), + .rxpolarity1 (), + .rxpolarity2 (), + .rxpolarity3 (), + .rxpolarity4 (), + .rxpolarity5 (), + .rxpolarity6 (), + .rxpolarity7 (), + .currentrxpreset0 (), + .currentrxpreset1 (), + .currentrxpreset2 (), + .currentrxpreset3 (), + .currentrxpreset4 (), + .currentrxpreset5 (), + .currentrxpreset6 (), + .currentrxpreset7 (), + .currentcoeff0 (), + .currentcoeff1 (), + .currentcoeff2 (), + .currentcoeff3 (), + .currentcoeff4 (), + .currentcoeff5 (), + .currentcoeff6 (), + .currentcoeff7 (), + .rxeqeval0 (), + .rxeqeval1 (), + .rxeqeval2 (), + .rxeqeval3 (), + .rxeqeval4 (), + .rxeqeval5 (), + .rxeqeval6 (), + .rxeqeval7 (), + .rxeqinprogress0 (), + .rxeqinprogress1 (), + .rxeqinprogress2 (), + .rxeqinprogress3 (), + .rxeqinprogress4 (), + .rxeqinprogress5 (), + .rxeqinprogress6 (), + .rxeqinprogress7 (), + .invalidreq0 (), + .invalidreq1 (), + .invalidreq2 (), + .invalidreq3 (), + .invalidreq4 (), + .invalidreq5 (), + .invalidreq6 (), + .invalidreq7 (), + .rxdata0 (32'd0), + .rxdata1 (32'd0), + .rxdata2 (32'd0), + .rxdata3 (32'd0), + .rxdata4 (32'd0), + .rxdata5 (32'd0), + .rxdata6 (32'd0), + .rxdata7 (32'd0), + .rxdatak0 (4'd0), + .rxdatak1 (4'd0), + .rxdatak2 (4'd0), + .rxdatak3 (4'd0), + .rxdatak4 (4'd0), + .rxdatak5 (4'd0), + .rxdatak6 (4'd0), + .rxdatak7 (4'd0), + .phystatus0 (1'b0), + .phystatus1 (1'b0), + .phystatus2 (1'b0), + .phystatus3 (1'b0), + .phystatus4 (1'b0), + .phystatus5 (1'b0), + .phystatus6 (1'b0), + .phystatus7 (1'b0), + .rxvalid0 (1'b0), + .rxvalid1 (1'b0), + .rxvalid2 (1'b0), + .rxvalid3 (1'b0), + .rxvalid4 (1'b0), + .rxvalid5 (1'b0), + .rxvalid6 (1'b0), + .rxvalid7 (1'b0), + .rxstatus0 (3'd0), + .rxstatus1 (3'd0), + .rxstatus2 (3'd0), + .rxstatus3 (3'd0), + .rxstatus4 (3'd0), + .rxstatus5 (3'd0), + .rxstatus6 (3'd0), + .rxstatus7 (3'd0), + .rxelecidle0 (1'b0), + .rxelecidle1 (1'b0), + .rxelecidle2 (1'b0), + .rxelecidle3 (1'b0), + .rxelecidle4 (1'b0), + .rxelecidle5 (1'b0), + .rxelecidle6 (1'b0), + .rxelecidle7 (1'b0), + .rxsynchd0 (2'd0), + .rxsynchd1 (2'd0), + .rxsynchd2 (2'd0), + .rxsynchd3 (2'd0), + .rxsynchd4 (2'd0), + .rxsynchd5 (2'd0), + .rxsynchd6 (2'd0), + .rxsynchd7 (2'd0), + .rxblkst0 (1'b0), + .rxblkst1 (1'b0), + .rxblkst2 (1'b0), + .rxblkst3 (1'b0), + .rxblkst4 (1'b0), + .rxblkst5 (1'b0), + .rxblkst6 (1'b0), + .rxblkst7 (1'b0), + .rxdataskip0 (1'b0), + .rxdataskip1 (1'b0), + .rxdataskip2 (1'b0), + .rxdataskip3 (1'b0), + .rxdataskip4 (1'b0), + .rxdataskip5 (1'b0), + .rxdataskip6 (1'b0), + .rxdataskip7 (1'b0), + .dirfeedback0 (6'd0), + .dirfeedback1 (6'd0), + .dirfeedback2 (6'd0), + .dirfeedback3 (6'd0), + .dirfeedback4 (6'd0), + .dirfeedback5 (6'd0), + .dirfeedback6 (6'd0), + .dirfeedback7 (6'd0), + .sim_pipe_mask_tx_pll_lock (1'b0), + .rx_in0 (pcie_ep_tx_p[0]), + .rx_in1 (pcie_ep_tx_p[1]), + .rx_in2 (pcie_ep_tx_p[2]), + .rx_in3 (pcie_ep_tx_p[3]), + .rx_in4 (pcie_ep_tx_p[4]), + .rx_in5 (pcie_ep_tx_p[5]), + .rx_in6 (pcie_ep_tx_p[6]), + .rx_in7 (pcie_ep_tx_p[7]), + .tx_out0 (pcie_ep_rx_p[0]), + .tx_out1 (pcie_ep_rx_p[1]), + .tx_out2 (pcie_ep_rx_p[2]), + .tx_out3 (pcie_ep_rx_p[3]), + .tx_out4 (pcie_ep_rx_p[4]), + .tx_out5 (pcie_ep_rx_p[5]), + .tx_out6 (pcie_ep_rx_p[6]), + .tx_out7 (pcie_ep_rx_p[7]), + .pm_linkst_in_l1 (), + .pm_linkst_in_l0s (), + .pm_state (), + .pm_dstate (), + .apps_pm_xmt_pme (0), + .apps_ready_entr_l23 (0), + .apps_pm_xmt_turnoff (0), + .app_init_rst (0), + .app_xfer_pending (0) +); + +fpga_core #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +fpga_core_inst ( + .clk(clk), + .rst(rst), + + /* + * GPIO + */ + .user_led(user_led), + + /* + * H-tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + .tx_ph_cdts(tx_ph_cdts), + .tx_pd_cdts(tx_pd_cdts), + .tx_nph_cdts(tx_nph_cdts), + .tx_npd_cdts(tx_npd_cdts), + .tx_cplh_cdts(tx_cplh_cdts), + .tx_cpld_cdts(tx_cpld_cdts), + .tx_hdr_cdts_consumed(tx_hdr_cdts_consumed), + .tx_data_cdts_consumed(tx_data_cdts_consumed), + .tx_cdts_type(tx_cdts_type), + .tx_cdts_data_value(tx_cdts_data_value), + + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga_core.v b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..c77980e43 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/fpga_core.v @@ -0,0 +1,176 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter SEG_COUNT = 1, + parameter SEG_DATA_WIDTH = 256, + parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32), + parameter TX_SEQ_NUM_WIDTH = 6, + parameter PCIE_TAG_COUNT = 256, + parameter BAR0_APERTURE = 24, + parameter BAR2_APERTURE = 24 +) +( + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [3:0] user_led, + + /* + * H-tile RX AVST interface + */ + input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data, + input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty, + input wire [SEG_COUNT-1:0] rx_st_sop, + input wire [SEG_COUNT-1:0] rx_st_eop, + input wire [SEG_COUNT-1:0] rx_st_valid, + output wire rx_st_ready, + input wire [SEG_COUNT-1:0] rx_st_vf_active, + input wire [SEG_COUNT*2-1:0] rx_st_func_num, + input wire [SEG_COUNT*11-1:0] rx_st_vf_num, + input wire [SEG_COUNT*3-1:0] rx_st_bar_range, + + output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data, + output wire [SEG_COUNT-1:0] tx_st_sop, + output wire [SEG_COUNT-1:0] tx_st_eop, + output wire [SEG_COUNT-1:0] tx_st_valid, + input wire tx_st_ready, + output wire [SEG_COUNT-1:0] tx_st_err, + + input wire [7:0] tx_ph_cdts, + input wire [11:0] tx_pd_cdts, + input wire [7:0] tx_nph_cdts, + input wire [11:0] tx_npd_cdts, + input wire [7:0] tx_cplh_cdts, + input wire [11:0] tx_cpld_cdts, + input wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed, + input wire [SEG_COUNT-1:0] tx_data_cdts_consumed, + input wire [SEG_COUNT*2-1:0] tx_cdts_type, + input wire [SEG_COUNT*1-1:0] tx_cdts_data_value, + + output wire app_msi_req, + input wire app_msi_ack, + output wire [2:0] app_msi_tc, + output wire [4:0] app_msi_num, + output wire [1:0] app_msi_func_num, + + input wire [31:0] tl_cfg_ctl, + input wire [4:0] tl_cfg_add, + input wire [1:0] tl_cfg_func +); + +assign user_led = 0; + +example_core_pcie_s10 #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .TX_SEQ_NUM_ENABLE(1), + .L_TILE(0), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(PCIE_TAG_COUNT), + .READ_TX_LIMIT(2**TX_SEQ_NUM_WIDTH), + .READ_TX_FC_ENABLE(1), + .WRITE_OP_TABLE_SIZE(2**TX_SEQ_NUM_WIDTH), + .WRITE_TX_LIMIT(2**TX_SEQ_NUM_WIDTH), + .WRITE_TX_FC_ENABLE(1), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +example_core_pcie_s10_inst ( + .clk(clk), + .rst(rst), + + /* + * H-tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + /* + * H-tile TX AVST interface + */ + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + /* + * H-tile TX flow control + */ + .tx_ph_cdts(tx_ph_cdts), + .tx_pd_cdts(tx_pd_cdts), + .tx_nph_cdts(tx_nph_cdts), + .tx_npd_cdts(tx_npd_cdts), + .tx_cplh_cdts(tx_cplh_cdts), + .tx_cpld_cdts(tx_cpld_cdts), + .tx_hdr_cdts_consumed(tx_hdr_cdts_consumed), + .tx_data_cdts_consumed(tx_data_cdts_consumed), + .tx_cdts_type(tx_cdts_type), + .tx_cdts_data_value(tx_cdts_data_value), + + /* + * H-tile MSI interrupt interface + */ + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + /* + * H-tile configuration interface + */ + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_reset.v b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..8c2dd529c --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_reset.v @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2014-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. + +*/ + +// Language: Verilog-2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset # +( + // depth of synchronizer + parameter N = 2 +) +( + input wire clk, + input wire rst, + output wire out +); + +(* srl_style = "register" *) +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) begin + sync_reg <= {N{1'b1}}; + end else begin + sync_reg <= {sync_reg[N-2:0], 1'b0}; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_signal.v b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/rtl/sync_signal.v @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/Makefile b/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..49474b6ee --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/Makefile @@ -0,0 +1,109 @@ +# 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 += ../../rtl/common/example_core_pcie_s10.v +VERILOG_SOURCES += ../../rtl/common/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/common/example_core.v +VERILOG_SOURCES += ../../rtl/common/axi_ram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if_rx.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_if_tx.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_s10_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_SEG_COUNT ?= 1 +export PARAM_SEG_DATA_WIDTH ?= 256 +export PARAM_SEG_EMPTY_WIDTH ?= $(shell python -c "print((($(PARAM_SEG_DATA_WIDTH)//32)-1).bit_length())" ) +export PARAM_TX_SEQ_NUM_WIDTH ?= 6 +export PARAM_PCIE_TAG_COUNT ?= 64 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).SEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GSEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -GSEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -GSEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/test_fpga_core.py b/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..d74ff2252 --- /dev/null +++ b/fpga/lib/pcie/example/S10MX_DK/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,306 @@ +""" + +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 + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = S10PcieDevice( + # configuration options + pcie_generation=3, + # pcie_link_width=8, + # pld_clk_frequency=250e6, + l_tile=False, + + # signals + # Clock and reset + # npor=dut.npor, + # pin_perst=dut.pin_perst, + # ninit_done=dut.ninit_done, + # pld_clk_inuse=dut.pld_clk_inuse, + # pld_core_ready=dut.pld_core_ready, + reset_status=dut.rst, + # clr_st=dut.clr_st, + # refclk=dut.refclk, + coreclkout_hip=dut.clk, + + # RX interface + rx_bus=S10RxBus.from_prefix(dut, "rx_st"), + + # TX interface + tx_bus=S10TxBus.from_prefix(dut, "tx_st"), + + # TX flow control + tx_ph_cdts=dut.tx_ph_cdts, + tx_pd_cdts=dut.tx_pd_cdts, + tx_nph_cdts=dut.tx_nph_cdts, + tx_npd_cdts=dut.tx_npd_cdts, + tx_cplh_cdts=dut.tx_cplh_cdts, + tx_cpld_cdts=dut.tx_cpld_cdts, + tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, + tx_data_cdts_consumed=dut.tx_data_cdts_consumed, + tx_cdts_type=dut.tx_cdts_type, + tx_cdts_data_value=dut.tx_cdts_data_value, + + # Hard IP status + # int_status=dut.int_status, + # int_status_common=dut.int_status_common, + # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, + # derr_rpl=dut.derr_rpl, + # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, + # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, + # rx_par_err=dut.rx_par_err, + # tx_par_err=dut.tx_par_err, + # ltssmstate=dut.ltssmstate, + # link_up=dut.link_up, + # lane_act=dut.lane_act, + # currentspeed=dut.currentspeed, + + # Power management + # pm_linkst_in_l1=dut.pm_linkst_in_l1, + # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, + # pm_state=dut.pm_state, + # pm_dstate=dut.pm_dstate, + # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, + # apps_ready_entr_l23=dut.apps_ready_entr_l23, + # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, + # app_init_rst=dut.app_init_rst, + # app_xfer_pending=dut.app_xfer_pending, + + # Interrupt interface + app_msi_req=dut.app_msi_req, + app_msi_ack=dut.app_msi_ack, + app_msi_tc=dut.app_msi_tc, + app_msi_num=dut.app_msi_num, + app_msi_func_num=dut.app_msi_func_num, + # app_int_sts=dut.app_int_sts, + + # Error interface + # app_err_valid=dut.app_err_valid, + # app_err_hdr=dut.app_err_hdr, + # app_err_info=dut.app_err_info, + # app_err_func_num=dut.app_err_func_num, + + # Configuration output + tl_cfg_func=dut.tl_cfg_func, + tl_cfg_add=dut.tl_cfg_add, + tl_cfg_ctl=dut.tl_cfg_ctl, + + # Configuration extension bus + # ceb_req=dut.ceb_req, + # ceb_ack=dut.ceb_ack, + # ceb_addr=dut.ceb_addr, + # ceb_din=dut.ceb_din, + # ceb_dout=dut.ceb_dout, + # ceb_wr=dut.ceb_wr, + # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, + # ceb_func_num=dut.ceb_func_num, + # ceb_vf_num=dut.ceb_vf_num, + # ceb_vf_active=dut.ceb_vf_active, + + # Hard IP reconfiguration interface + # hip_reconfig_clk=dut.hip_reconfig_clk, + # hip_reconfig_address=dut.hip_reconfig_address, + # hip_reconfig_read=dut.hip_reconfig_read, + # hip_reconfig_readdata=dut.hip_reconfig_readdata, + # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, + # hip_reconfig_write=dut.hip_reconfig_write, + # hip_reconfig_writedata=dut.hip_reconfig_writedata, + # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(2, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + + # enable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 3) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "example_core_pcie_s10.v"), + os.path.join(rtl_dir, "common", "example_core_pcie.v"), + os.path.join(rtl_dir, "common", "example_core.v"), + os.path.join(rtl_dir, "common", "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_rx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_tx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['SEG_COUNT'] = 1 + parameters['SEG_DATA_WIDTH'] = 256 + parameters['SEG_EMPTY_WIDTH'] = (parameters['SEG_DATA_WIDTH'] // 32 - 1).bit_length() + parameters['TX_SEQ_NUM_WIDTH'] = 6 + parameters['PCIE_TAG_COUNT'] = 64 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/VCU108/fpga_axi/ip/pcie3_ultrascale_0.tcl b/fpga/lib/pcie/example/VCU108/fpga_axi/ip/pcie3_ultrascale_0.tcl index 89c2b7473..535e29ce4 100644 --- a/fpga/lib/pcie/example/VCU108/fpga_axi/ip/pcie3_ultrascale_0.tcl +++ b/fpga/lib/pcie/example/VCU108/fpga_axi/ip/pcie3_ultrascale_0.tcl @@ -8,16 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_width {256_bit} \ CONFIG.extended_tag_field {true} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ - CONFIG.pf0_class_code_base {02} \ - CONFIG.pf0_class_code_sub {00} \ + CONFIG.PF0_SUBSYSTEM_ID {806c} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/VCU118/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/VCU118/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..86e78fdf1 100644 --- a/fpga/lib/pcie/example/VCU118/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/VCU118/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {9076} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/VCU1525/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/VCU1525/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..e54bf9d7b 100644 --- a/fpga/lib/pcie/example/VCU1525/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/VCU1525/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {95f5} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/ZCU106/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/ZCU106/fpga_axi/ip/pcie4_uscale_plus_0.tcl index d448a77d6..a0d1e8c3f 100644 --- a/fpga/lib/pcie/example/ZCU106/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/ZCU106/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {128_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {906a} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/example/common/driver/example/example_driver.c b/fpga/lib/pcie/example/common/driver/example/example_driver.c index dd4bcc7ba..b354be3a2 100644 --- a/fpga/lib/pcie/example/common/driver/example/example_driver.c +++ b/fpga/lib/pcie/example/common/driver/example/example_driver.c @@ -1,26 +1,25 @@ +// SPDX-License-Identifier: MIT /* - -Copyright (c) 2018-2021 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. - -*/ + * Copyright (c) 2018-2021 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. + */ #include "example_driver.h" #include @@ -28,7 +27,7 @@ THE SOFTWARE. #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) #include #endif @@ -75,45 +74,47 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(dev, DRIVER_NAME " probe"); dev_info(dev, " Vendor: 0x%04x", pdev->vendor); dev_info(dev, " Device: 0x%04x", pdev->device); + dev_info(dev, " Subsystem vendor: 0x%04x", pdev->subsystem_vendor); + dev_info(dev, " Subsystem device: 0x%04x", pdev->subsystem_device); dev_info(dev, " Class: 0x%06x", pdev->class); dev_info(dev, " PCI ID: %04x:%02x:%02x.%d", pci_domain_nr(pdev->bus), - pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); if (pdev->pcie_cap) { u16 devctl; u32 lnkcap; u16 lnksta; + pci_read_config_word(pdev, pdev->pcie_cap + PCI_EXP_DEVCTL, &devctl); pci_read_config_dword(pdev, pdev->pcie_cap + PCI_EXP_LNKCAP, &lnkcap); pci_read_config_word(pdev, pdev->pcie_cap + PCI_EXP_LNKSTA, &lnksta); + dev_info(dev, " Max payload size: %d bytes", - 128 << ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5)); + 128 << ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5)); dev_info(dev, " Max read request size: %d bytes", - 128 << ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12)); + 128 << ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12)); dev_info(dev, " Link capability: gen %d x%d", - lnkcap & PCI_EXP_LNKCAP_SLS, (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4); + lnkcap & PCI_EXP_LNKCAP_SLS, (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4); dev_info(dev, " Link status: gen %d x%d", - lnksta & PCI_EXP_LNKSTA_CLS, (lnksta & PCI_EXP_LNKSTA_NLW) >> 4); + lnksta & PCI_EXP_LNKSTA_CLS, (lnksta & PCI_EXP_LNKSTA_NLW) >> 4); dev_info(dev, " Relaxed ordering: %s", - devctl & PCI_EXP_DEVCTL_RELAX_EN ? "enabled" : "disabled"); + devctl & PCI_EXP_DEVCTL_RELAX_EN ? "enabled" : "disabled"); dev_info(dev, " Phantom functions: %s", - devctl & PCI_EXP_DEVCTL_PHANTOM ? "enabled" : "disabled"); + devctl & PCI_EXP_DEVCTL_PHANTOM ? "enabled" : "disabled"); dev_info(dev, " Extended tags: %s", - devctl & PCI_EXP_DEVCTL_EXT_TAG ? "enabled" : "disabled"); + devctl & PCI_EXP_DEVCTL_EXT_TAG ? "enabled" : "disabled"); dev_info(dev, " No snoop: %s", - devctl & PCI_EXP_DEVCTL_NOSNOOP_EN ? "enabled" : "disabled"); + devctl & PCI_EXP_DEVCTL_NOSNOOP_EN ? "enabled" : "disabled"); } #ifdef CONFIG_NUMA dev_info(dev, " NUMA node: %d", pdev->dev.numa_node); #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) pcie_print_link_status(pdev); #endif edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL); - if (!edev) { - dev_err(dev, "Failed to allocate memory"); + if (!edev) return -ENOMEM; - } edev->pdev = pdev; pci_set_drvdata(pdev, edev); @@ -121,20 +122,18 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) // Allocate DMA buffer edev->dma_region_len = 16 * 1024; edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, - &edev->dma_region_addr, - GFP_KERNEL | __GFP_ZERO); + &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); if (!edev->dma_region) { - dev_err(dev, "Failed to allocate DMA buffer"); ret = -ENOMEM; goto fail_dma_alloc; } dev_info(dev, "Allocated DMA region virt %p, phys %p", - edev->dma_region, (void *)edev->dma_region_addr); + edev->dma_region, (void *)edev->dma_region_addr); // Disable ASPM pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | - PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); + PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); // Enable device ret = pci_enable_device_mem(pdev); @@ -191,7 +190,7 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(dev, "read test data"); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, - edev->dma_region, 256, true); + edev->dma_region, 256, true); dev_info(dev, "check DMA enable"); dev_info(dev, "%08x", ioread32(edev->bar[0] + 0x000000)); @@ -202,6 +201,9 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(dev, "check DMA enable"); dev_info(dev, "%08x", ioread32(edev->bar[0] + 0x000000)); + dev_info(dev, "enable interrupts"); + iowrite32(0x3, edev->bar[0] + 0x000008); + dev_info(dev, "start copy to card"); iowrite32((edev->dma_region_addr + 0x0000) & 0xffffffff, edev->bar[0] + 0x000100); iowrite32(((edev->dma_region_addr + 0x0000) >> 32) & 0xffffffff, edev->bar[0] + 0x000104); @@ -230,7 +232,7 @@ static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(dev, "read test data"); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, - edev->dma_region + 0x0200, 256, true); + edev->dma_region + 0x0200, 256, true); // probe complete return 0; @@ -280,11 +282,13 @@ static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) for (i = 0; i < 6; i++) { resource_size_t bar_start = pci_resource_start(pdev, i); + if (bar_start) { resource_size_t bar_end = pci_resource_end(pdev, i); unsigned long bar_flags = pci_resource_flags(pdev, i); + dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); + i, bar_start, bar_end, bar_flags); } } @@ -300,6 +304,7 @@ static int map_bars(struct example_dev *edev, struct pci_dev *pdev) resource_size_t bar_start = pci_resource_start(pdev, i); resource_size_t bar_end = pci_resource_end(pdev, i); resource_size_t bar_len = bar_end - bar_start + 1; + edev->bar_len[i] = bar_len; if (!bar_start || !bar_end) { diff --git a/fpga/lib/pcie/example/common/driver/example/example_driver.h b/fpga/lib/pcie/example/common/driver/example/example_driver.h index 6ef2857a6..6de92f937 100644 --- a/fpga/lib/pcie/example/common/driver/example/example_driver.h +++ b/fpga/lib/pcie/example/common/driver/example/example_driver.h @@ -1,26 +1,25 @@ +/* SPDX-License-Identifier: MIT */ /* - -Copyright (c) 2018-2021 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. - -*/ + * Copyright (c) 2018-2021 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. + */ #ifndef EXAMPLE_DRIVER_H #define EXAMPLE_DRIVER_H diff --git a/fpga/lib/pcie/example/common/rtl/axi_ram.v b/fpga/lib/pcie/example/common/rtl/axi_ram.v new file mode 100644 index 000000000..7eea20315 --- /dev/null +++ b/fpga/lib/pcie/example/common/rtl/axi_ram.v @@ -0,0 +1,373 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * AXI4 RAM + */ +module axi_ram # +( + // Width of data bus in bits + parameter DATA_WIDTH = 32, + // Width of address bus in bits + parameter ADDR_WIDTH = 16, + // Width of wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH/8), + // Width of ID signal + parameter ID_WIDTH = 8, + // Extra pipeline register on output + parameter PIPELINE_OUTPUT = 0 +) +( + input wire clk, + input wire rst, + + input wire [ID_WIDTH-1:0] s_axi_awid, + input wire [ADDR_WIDTH-1:0] s_axi_awaddr, + input wire [7:0] s_axi_awlen, + input wire [2:0] s_axi_awsize, + input wire [1:0] s_axi_awburst, + input wire s_axi_awlock, + input wire [3:0] s_axi_awcache, + input wire [2:0] s_axi_awprot, + input wire s_axi_awvalid, + output wire s_axi_awready, + input wire [DATA_WIDTH-1:0] s_axi_wdata, + input wire [STRB_WIDTH-1:0] s_axi_wstrb, + input wire s_axi_wlast, + input wire s_axi_wvalid, + output wire s_axi_wready, + output wire [ID_WIDTH-1:0] s_axi_bid, + output wire [1:0] s_axi_bresp, + output wire s_axi_bvalid, + input wire s_axi_bready, + input wire [ID_WIDTH-1:0] s_axi_arid, + input wire [ADDR_WIDTH-1:0] s_axi_araddr, + input wire [7:0] s_axi_arlen, + input wire [2:0] s_axi_arsize, + input wire [1:0] s_axi_arburst, + input wire s_axi_arlock, + input wire [3:0] s_axi_arcache, + input wire [2:0] s_axi_arprot, + input wire s_axi_arvalid, + output wire s_axi_arready, + output wire [ID_WIDTH-1:0] s_axi_rid, + output wire [DATA_WIDTH-1:0] s_axi_rdata, + output wire [1:0] s_axi_rresp, + output wire s_axi_rlast, + output wire s_axi_rvalid, + input wire s_axi_rready +); + +parameter VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH); +parameter WORD_WIDTH = STRB_WIDTH; +parameter WORD_SIZE = DATA_WIDTH/WORD_WIDTH; + +// bus width assertions +initial begin + if (WORD_SIZE * STRB_WIDTH != DATA_WIDTH) begin + $error("Error: AXI data width not evenly divisble (instance %m)"); + $finish; + end + + if (2**$clog2(WORD_WIDTH) != WORD_WIDTH) begin + $error("Error: AXI word width must be even power of two (instance %m)"); + $finish; + end +end + +localparam [0:0] + READ_STATE_IDLE = 1'd0, + READ_STATE_BURST = 1'd1; + +reg [0:0] read_state_reg = READ_STATE_IDLE, read_state_next; + +localparam [1:0] + WRITE_STATE_IDLE = 2'd0, + WRITE_STATE_BURST = 2'd1, + WRITE_STATE_RESP = 2'd2; + +reg [1:0] write_state_reg = WRITE_STATE_IDLE, write_state_next; + +reg mem_wr_en; +reg mem_rd_en; + +reg [ID_WIDTH-1:0] read_id_reg = {ID_WIDTH{1'b0}}, read_id_next; +reg [ADDR_WIDTH-1:0] read_addr_reg = {ADDR_WIDTH{1'b0}}, read_addr_next; +reg [7:0] read_count_reg = 8'd0, read_count_next; +reg [2:0] read_size_reg = 3'd0, read_size_next; +reg [1:0] read_burst_reg = 2'd0, read_burst_next; +reg [ID_WIDTH-1:0] write_id_reg = {ID_WIDTH{1'b0}}, write_id_next; +reg [ADDR_WIDTH-1:0] write_addr_reg = {ADDR_WIDTH{1'b0}}, write_addr_next; +reg [7:0] write_count_reg = 8'd0, write_count_next; +reg [2:0] write_size_reg = 3'd0, write_size_next; +reg [1:0] write_burst_reg = 2'd0, write_burst_next; + +reg s_axi_awready_reg = 1'b0, s_axi_awready_next; +reg s_axi_wready_reg = 1'b0, s_axi_wready_next; +reg [ID_WIDTH-1:0] s_axi_bid_reg = {ID_WIDTH{1'b0}}, s_axi_bid_next; +reg s_axi_bvalid_reg = 1'b0, s_axi_bvalid_next; +reg s_axi_arready_reg = 1'b0, s_axi_arready_next; +reg [ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}, s_axi_rid_next; +reg [DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}, s_axi_rdata_next; +reg s_axi_rlast_reg = 1'b0, s_axi_rlast_next; +reg s_axi_rvalid_reg = 1'b0, s_axi_rvalid_next; +reg [ID_WIDTH-1:0] s_axi_rid_pipe_reg = {ID_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] s_axi_rdata_pipe_reg = {DATA_WIDTH{1'b0}}; +reg s_axi_rlast_pipe_reg = 1'b0; +reg s_axi_rvalid_pipe_reg = 1'b0; + +// (* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH-1:0] mem[(2**VALID_ADDR_WIDTH)-1:0]; + +wire [VALID_ADDR_WIDTH-1:0] s_axi_awaddr_valid = s_axi_awaddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH); +wire [VALID_ADDR_WIDTH-1:0] s_axi_araddr_valid = s_axi_araddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH); +wire [VALID_ADDR_WIDTH-1:0] read_addr_valid = read_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); +wire [VALID_ADDR_WIDTH-1:0] write_addr_valid = write_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); + +assign s_axi_awready = s_axi_awready_reg; +assign s_axi_wready = s_axi_wready_reg; +assign s_axi_bid = s_axi_bid_reg; +assign s_axi_bresp = 2'b00; +assign s_axi_bvalid = s_axi_bvalid_reg; +assign s_axi_arready = s_axi_arready_reg; +assign s_axi_rid = PIPELINE_OUTPUT ? s_axi_rid_pipe_reg : s_axi_rid_reg; +assign s_axi_rdata = PIPELINE_OUTPUT ? s_axi_rdata_pipe_reg : s_axi_rdata_reg; +assign s_axi_rresp = 2'b00; +assign s_axi_rlast = PIPELINE_OUTPUT ? s_axi_rlast_pipe_reg : s_axi_rlast_reg; +assign s_axi_rvalid = PIPELINE_OUTPUT ? s_axi_rvalid_pipe_reg : s_axi_rvalid_reg; + +integer i, j; + +initial begin + // two nested loops for smaller number of iterations per loop + // workaround for synthesizer complaints about large loop counts + for (i = 0; i < 2**VALID_ADDR_WIDTH; i = i + 2**(VALID_ADDR_WIDTH/2)) begin + for (j = i; j < i + 2**(VALID_ADDR_WIDTH/2); j = j + 1) begin + mem[j] = 0; + end + end +end + +always @* begin + write_state_next = WRITE_STATE_IDLE; + + mem_wr_en = 1'b0; + + write_id_next = write_id_reg; + write_addr_next = write_addr_reg; + write_count_next = write_count_reg; + write_size_next = write_size_reg; + write_burst_next = write_burst_reg; + + s_axi_awready_next = 1'b0; + s_axi_wready_next = 1'b0; + s_axi_bid_next = s_axi_bid_reg; + s_axi_bvalid_next = s_axi_bvalid_reg && !s_axi_bready; + + case (write_state_reg) + WRITE_STATE_IDLE: begin + s_axi_awready_next = 1'b1; + + if (s_axi_awready && s_axi_awvalid) begin + write_id_next = s_axi_awid; + write_addr_next = s_axi_awaddr; + write_count_next = s_axi_awlen; + write_size_next = s_axi_awsize < $clog2(STRB_WIDTH) ? s_axi_awsize : $clog2(STRB_WIDTH); + write_burst_next = s_axi_awburst; + + s_axi_awready_next = 1'b0; + s_axi_wready_next = 1'b1; + write_state_next = WRITE_STATE_BURST; + end else begin + write_state_next = WRITE_STATE_IDLE; + end + end + WRITE_STATE_BURST: begin + s_axi_wready_next = 1'b1; + + if (s_axi_wready && s_axi_wvalid) begin + mem_wr_en = 1'b1; + if (write_burst_reg != 2'b00) begin + write_addr_next = write_addr_reg + (1 << write_size_reg); + end + write_count_next = write_count_reg - 1; + if (write_count_reg > 0) begin + write_state_next = WRITE_STATE_BURST; + end else begin + s_axi_wready_next = 1'b0; + if (s_axi_bready || !s_axi_bvalid) begin + s_axi_bid_next = write_id_reg; + s_axi_bvalid_next = 1'b1; + s_axi_awready_next = 1'b1; + write_state_next = WRITE_STATE_IDLE; + end else begin + write_state_next = WRITE_STATE_RESP; + end + end + end else begin + write_state_next = WRITE_STATE_BURST; + end + end + WRITE_STATE_RESP: begin + if (s_axi_bready || !s_axi_bvalid) begin + s_axi_bid_next = write_id_reg; + s_axi_bvalid_next = 1'b1; + s_axi_awready_next = 1'b1; + write_state_next = WRITE_STATE_IDLE; + end else begin + write_state_next = WRITE_STATE_RESP; + end + end + endcase +end + +always @(posedge clk) begin + write_state_reg <= write_state_next; + + write_id_reg <= write_id_next; + write_addr_reg <= write_addr_next; + write_count_reg <= write_count_next; + write_size_reg <= write_size_next; + write_burst_reg <= write_burst_next; + + s_axi_awready_reg <= s_axi_awready_next; + s_axi_wready_reg <= s_axi_wready_next; + s_axi_bid_reg <= s_axi_bid_next; + s_axi_bvalid_reg <= s_axi_bvalid_next; + + for (i = 0; i < WORD_WIDTH; i = i + 1) begin + if (mem_wr_en & s_axi_wstrb[i]) begin + mem[write_addr_valid][WORD_SIZE*i +: WORD_SIZE] <= s_axi_wdata[WORD_SIZE*i +: WORD_SIZE]; + end + end + + if (rst) begin + write_state_reg <= WRITE_STATE_IDLE; + + s_axi_awready_reg <= 1'b0; + s_axi_wready_reg <= 1'b0; + s_axi_bvalid_reg <= 1'b0; + end +end + +always @* begin + read_state_next = READ_STATE_IDLE; + + mem_rd_en = 1'b0; + + s_axi_rid_next = s_axi_rid_reg; + s_axi_rlast_next = s_axi_rlast_reg; + s_axi_rvalid_next = s_axi_rvalid_reg && !(s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg)); + + read_id_next = read_id_reg; + read_addr_next = read_addr_reg; + read_count_next = read_count_reg; + read_size_next = read_size_reg; + read_burst_next = read_burst_reg; + + s_axi_arready_next = 1'b0; + + case (read_state_reg) + READ_STATE_IDLE: begin + s_axi_arready_next = 1'b1; + + if (s_axi_arready && s_axi_arvalid) begin + read_id_next = s_axi_arid; + read_addr_next = s_axi_araddr; + read_count_next = s_axi_arlen; + read_size_next = s_axi_arsize < $clog2(STRB_WIDTH) ? s_axi_arsize : $clog2(STRB_WIDTH); + read_burst_next = s_axi_arburst; + + s_axi_arready_next = 1'b0; + read_state_next = READ_STATE_BURST; + end else begin + read_state_next = READ_STATE_IDLE; + end + end + READ_STATE_BURST: begin + if (s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg) || !s_axi_rvalid_reg) begin + mem_rd_en = 1'b1; + s_axi_rvalid_next = 1'b1; + s_axi_rid_next = read_id_reg; + s_axi_rlast_next = read_count_reg == 0; + if (read_burst_reg != 2'b00) begin + read_addr_next = read_addr_reg + (1 << read_size_reg); + end + read_count_next = read_count_reg - 1; + if (read_count_reg > 0) begin + read_state_next = READ_STATE_BURST; + end else begin + s_axi_arready_next = 1'b1; + read_state_next = READ_STATE_IDLE; + end + end else begin + read_state_next = READ_STATE_BURST; + end + end + endcase +end + +always @(posedge clk) begin + read_state_reg <= read_state_next; + + read_id_reg <= read_id_next; + read_addr_reg <= read_addr_next; + read_count_reg <= read_count_next; + read_size_reg <= read_size_next; + read_burst_reg <= read_burst_next; + + s_axi_arready_reg <= s_axi_arready_next; + s_axi_rid_reg <= s_axi_rid_next; + s_axi_rlast_reg <= s_axi_rlast_next; + s_axi_rvalid_reg <= s_axi_rvalid_next; + + if (mem_rd_en) begin + s_axi_rdata_reg <= mem[read_addr_valid]; + end + + if (!s_axi_rvalid_pipe_reg || s_axi_rready) begin + s_axi_rid_pipe_reg <= s_axi_rid_reg; + s_axi_rdata_pipe_reg <= s_axi_rdata_reg; + s_axi_rlast_pipe_reg <= s_axi_rlast_reg; + s_axi_rvalid_pipe_reg <= s_axi_rvalid_reg; + end + + if (rst) begin + read_state_reg <= READ_STATE_IDLE; + + s_axi_arready_reg <= 1'b0; + s_axi_rvalid_reg <= 1'b0; + s_axi_rvalid_pipe_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/common/rtl/example_core.v b/fpga/lib/pcie/example/common/rtl/example_core.v new file mode 100644 index 000000000..1529fb759 --- /dev/null +++ b/fpga/lib/pcie/example/common/rtl/example_core.v @@ -0,0 +1,661 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Example design core logic + */ +module example_core # +( + // Width of AXI lite data bus in bits + parameter AXIL_DATA_WIDTH = 32, + // Width of AXI lite address bus in bits + parameter AXIL_ADDR_WIDTH = 64, + // Width of AXI lite wstrb (width of data bus in words) + parameter AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8), + // DMA address width + parameter DMA_ADDR_WIDTH = 64, + // DMA Length field width + parameter DMA_LEN_WIDTH = 16, + // DMA Tag field width + parameter DMA_TAG_WIDTH = 8, + // RAM segment count + parameter RAM_SEG_COUNT = 2, + // RAM segment data width + parameter RAM_SEG_DATA_WIDTH = 256*2/RAM_SEG_COUNT, + // RAM segment address width + parameter RAM_SEG_ADDR_WIDTH = 8, + // RAM segment byte enable width + parameter RAM_SEG_BE_WIDTH = RAM_SEG_DATA_WIDTH/8, + // RAM select width + parameter RAM_SEL_WIDTH = 2, + // RAM address width + parameter RAM_ADDR_WIDTH = RAM_SEG_ADDR_WIDTH+$clog2(RAM_SEG_COUNT)+$clog2(RAM_SEG_BE_WIDTH) +) +( + input wire clk, + input wire rst, + + /* + * AXI Lite control interface + */ + input wire [AXIL_ADDR_WIDTH-1:0] s_axil_ctrl_awaddr, + input wire [2:0] s_axil_ctrl_awprot, + input wire s_axil_ctrl_awvalid, + output wire s_axil_ctrl_awready, + input wire [AXIL_DATA_WIDTH-1:0] s_axil_ctrl_wdata, + input wire [AXIL_STRB_WIDTH-1:0] s_axil_ctrl_wstrb, + input wire s_axil_ctrl_wvalid, + output wire s_axil_ctrl_wready, + output wire [1:0] s_axil_ctrl_bresp, + output wire s_axil_ctrl_bvalid, + input wire s_axil_ctrl_bready, + input wire [AXIL_ADDR_WIDTH-1:0] s_axil_ctrl_araddr, + input wire [2:0] s_axil_ctrl_arprot, + input wire s_axil_ctrl_arvalid, + output wire s_axil_ctrl_arready, + output wire [AXIL_DATA_WIDTH-1:0] s_axil_ctrl_rdata, + output wire [1:0] s_axil_ctrl_rresp, + output wire s_axil_ctrl_rvalid, + input wire s_axil_ctrl_rready, + + /* + * AXI read descriptor output + */ + output wire [DMA_ADDR_WIDTH-1:0] m_axis_dma_read_desc_dma_addr, + output wire [RAM_SEL_WIDTH-1:0] m_axis_dma_read_desc_ram_sel, + output wire [RAM_ADDR_WIDTH-1:0] m_axis_dma_read_desc_ram_addr, + output wire [DMA_LEN_WIDTH-1:0] m_axis_dma_read_desc_len, + output wire [DMA_TAG_WIDTH-1:0] m_axis_dma_read_desc_tag, + output wire m_axis_dma_read_desc_valid, + input wire m_axis_dma_read_desc_ready, + + /* + * AXI read descriptor status input + */ + input wire [DMA_TAG_WIDTH-1:0] s_axis_dma_read_desc_status_tag, + input wire [3:0] s_axis_dma_read_desc_status_error, + input wire s_axis_dma_read_desc_status_valid, + + /* + * AXI write descriptor output + */ + output wire [DMA_ADDR_WIDTH-1:0] m_axis_dma_write_desc_dma_addr, + output wire [RAM_SEL_WIDTH-1:0] m_axis_dma_write_desc_ram_sel, + output wire [RAM_ADDR_WIDTH-1:0] m_axis_dma_write_desc_ram_addr, + output wire [DMA_LEN_WIDTH-1:0] m_axis_dma_write_desc_len, + output wire [DMA_TAG_WIDTH-1:0] m_axis_dma_write_desc_tag, + output wire m_axis_dma_write_desc_valid, + input wire m_axis_dma_write_desc_ready, + + /* + * AXI write descriptor status input + */ + input wire [DMA_TAG_WIDTH-1:0] s_axis_dma_write_desc_status_tag, + input wire [3:0] s_axis_dma_write_desc_status_error, + input wire s_axis_dma_write_desc_status_valid, + + /* + * RAM interface + */ + input wire [RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel, + input wire [RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0] ram_rd_cmd_addr, + input wire [RAM_SEG_COUNT-1:0] ram_rd_cmd_valid, + output wire [RAM_SEG_COUNT-1:0] ram_rd_cmd_ready, + output wire [RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-1:0] ram_rd_resp_data, + output wire [RAM_SEG_COUNT-1:0] ram_rd_resp_valid, + input wire [RAM_SEG_COUNT-1:0] ram_rd_resp_ready, + input wire [RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0] ram_wr_cmd_sel, + input wire [RAM_SEG_COUNT*RAM_SEG_BE_WIDTH-1:0] ram_wr_cmd_be, + input wire [RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0] ram_wr_cmd_addr, + input wire [RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-1:0] ram_wr_cmd_data, + input wire [RAM_SEG_COUNT-1:0] ram_wr_cmd_valid, + output wire [RAM_SEG_COUNT-1:0] ram_wr_cmd_ready, + output wire [RAM_SEG_COUNT-1:0] ram_wr_done, + + /* + * MSI request outputs + */ + output wire [31:0] msi_irq +); + +dma_psdpram #( + .SIZE(16384), + .SEG_COUNT(RAM_SEG_COUNT), + .SEG_DATA_WIDTH(RAM_SEG_DATA_WIDTH), + .SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH), + .SEG_BE_WIDTH(RAM_SEG_BE_WIDTH), + .PIPELINE(2) +) +dma_ram_inst ( + .clk(clk), + .rst(rst), + + /* + * Write port + */ + .wr_cmd_be(ram_wr_cmd_be), + .wr_cmd_addr(ram_wr_cmd_addr), + .wr_cmd_data(ram_wr_cmd_data), + .wr_cmd_valid(ram_wr_cmd_valid), + .wr_cmd_ready(ram_wr_cmd_ready), + .wr_done(ram_wr_done), + + /* + * Read port + */ + .rd_cmd_addr(ram_rd_cmd_addr), + .rd_cmd_valid(ram_rd_cmd_valid), + .rd_cmd_ready(ram_rd_cmd_ready), + .rd_resp_data(ram_rd_resp_data), + .rd_resp_valid(ram_rd_resp_valid), + .rd_resp_ready(ram_rd_resp_ready) +); + +// control registers +reg axil_ctrl_awready_reg = 1'b0, axil_ctrl_awready_next; +reg axil_ctrl_wready_reg = 1'b0, axil_ctrl_wready_next; +reg [1:0] axil_ctrl_bresp_reg = 2'b00, axil_ctrl_bresp_next; +reg axil_ctrl_bvalid_reg = 1'b0, axil_ctrl_bvalid_next; +reg axil_ctrl_arready_reg = 1'b0, axil_ctrl_arready_next; +reg [AXIL_DATA_WIDTH-1:0] axil_ctrl_rdata_reg = {AXIL_DATA_WIDTH{1'b0}}, axil_ctrl_rdata_next; +reg [1:0] axil_ctrl_rresp_reg = 2'b00, axil_ctrl_rresp_next; +reg axil_ctrl_rvalid_reg = 1'b0, axil_ctrl_rvalid_next; + +reg [63:0] cycle_count_reg = 0; +reg [15:0] dma_read_active_count_reg = 0; +reg [15:0] dma_write_active_count_reg = 0; + +reg [DMA_ADDR_WIDTH-1:0] dma_read_desc_dma_addr_reg = 0, dma_read_desc_dma_addr_next; +reg [RAM_ADDR_WIDTH-1:0] dma_read_desc_ram_addr_reg = 0, dma_read_desc_ram_addr_next; +reg [DMA_LEN_WIDTH-1:0] dma_read_desc_len_reg = 0, dma_read_desc_len_next; +reg [DMA_TAG_WIDTH-1:0] dma_read_desc_tag_reg = 0, dma_read_desc_tag_next; +reg dma_read_desc_valid_reg = 0, dma_read_desc_valid_next; + +reg [DMA_TAG_WIDTH-1:0] dma_read_desc_status_tag_reg = 0, dma_read_desc_status_tag_next; +reg [3:0] dma_read_desc_status_error_reg = 0, dma_read_desc_status_error_next; +reg dma_read_desc_status_valid_reg = 0, dma_read_desc_status_valid_next; + +reg [DMA_ADDR_WIDTH-1:0] dma_write_desc_dma_addr_reg = 0, dma_write_desc_dma_addr_next; +reg [RAM_ADDR_WIDTH-1:0] dma_write_desc_ram_addr_reg = 0, dma_write_desc_ram_addr_next; +reg [DMA_LEN_WIDTH-1:0] dma_write_desc_len_reg = 0, dma_write_desc_len_next; +reg [DMA_TAG_WIDTH-1:0] dma_write_desc_tag_reg = 0, dma_write_desc_tag_next; +reg dma_write_desc_valid_reg = 0, dma_write_desc_valid_next; + +reg [DMA_TAG_WIDTH-1:0] dma_write_desc_status_tag_reg = 0, dma_write_desc_status_tag_next; +reg [3:0] dma_write_desc_status_error_reg = 0, dma_write_desc_status_error_next; +reg dma_write_desc_status_valid_reg = 0, dma_write_desc_status_valid_next; + +reg dma_enable_reg = 0, dma_enable_next; +reg dma_rd_int_en_reg = 0, dma_rd_int_en_next; +reg dma_wr_int_en_reg = 0, dma_wr_int_en_next; + +reg dma_read_block_run_reg = 1'b0, dma_read_block_run_next; +reg [DMA_LEN_WIDTH-1:0] dma_read_block_len_reg = 0, dma_read_block_len_next; +reg [31:0] dma_read_block_count_reg = 0, dma_read_block_count_next; +reg [63:0] dma_read_block_cycle_count_reg = 0, dma_read_block_cycle_count_next; +reg [DMA_ADDR_WIDTH-1:0] dma_read_block_dma_base_addr_reg = 0, dma_read_block_dma_base_addr_next; +reg [DMA_ADDR_WIDTH-1:0] dma_read_block_dma_offset_reg = 0, dma_read_block_dma_offset_next; +reg [DMA_ADDR_WIDTH-1:0] dma_read_block_dma_offset_mask_reg = 0, dma_read_block_dma_offset_mask_next; +reg [DMA_ADDR_WIDTH-1:0] dma_read_block_dma_stride_reg = 0, dma_read_block_dma_stride_next; +reg [RAM_ADDR_WIDTH-1:0] dma_read_block_ram_base_addr_reg = 0, dma_read_block_ram_base_addr_next; +reg [RAM_ADDR_WIDTH-1:0] dma_read_block_ram_offset_reg = 0, dma_read_block_ram_offset_next; +reg [RAM_ADDR_WIDTH-1:0] dma_read_block_ram_offset_mask_reg = 0, dma_read_block_ram_offset_mask_next; +reg [RAM_ADDR_WIDTH-1:0] dma_read_block_ram_stride_reg = 0, dma_read_block_ram_stride_next; + +reg dma_write_block_run_reg = 1'b0, dma_write_block_run_next; +reg [DMA_LEN_WIDTH-1:0] dma_write_block_len_reg = 0, dma_write_block_len_next; +reg [31:0] dma_write_block_count_reg = 0, dma_write_block_count_next; +reg [63:0] dma_write_block_cycle_count_reg = 0, dma_write_block_cycle_count_next; +reg [DMA_ADDR_WIDTH-1:0] dma_write_block_dma_base_addr_reg = 0, dma_write_block_dma_base_addr_next; +reg [DMA_ADDR_WIDTH-1:0] dma_write_block_dma_offset_reg = 0, dma_write_block_dma_offset_next; +reg [DMA_ADDR_WIDTH-1:0] dma_write_block_dma_offset_mask_reg = 0, dma_write_block_dma_offset_mask_next; +reg [DMA_ADDR_WIDTH-1:0] dma_write_block_dma_stride_reg = 0, dma_write_block_dma_stride_next; +reg [RAM_ADDR_WIDTH-1:0] dma_write_block_ram_base_addr_reg = 0, dma_write_block_ram_base_addr_next; +reg [RAM_ADDR_WIDTH-1:0] dma_write_block_ram_offset_reg = 0, dma_write_block_ram_offset_next; +reg [RAM_ADDR_WIDTH-1:0] dma_write_block_ram_offset_mask_reg = 0, dma_write_block_ram_offset_mask_next; +reg [RAM_ADDR_WIDTH-1:0] dma_write_block_ram_stride_reg = 0, dma_write_block_ram_stride_next; + +assign s_axil_ctrl_awready = axil_ctrl_awready_reg; +assign s_axil_ctrl_wready = axil_ctrl_wready_reg; +assign s_axil_ctrl_bresp = axil_ctrl_bresp_reg; +assign s_axil_ctrl_bvalid = axil_ctrl_bvalid_reg; +assign s_axil_ctrl_arready = axil_ctrl_arready_reg; +assign s_axil_ctrl_rdata = axil_ctrl_rdata_reg; +assign s_axil_ctrl_rresp = axil_ctrl_rresp_reg; +assign s_axil_ctrl_rvalid = axil_ctrl_rvalid_reg; + +assign m_axis_dma_read_desc_dma_addr = dma_read_desc_dma_addr_reg; +assign m_axis_dma_read_desc_ram_sel = 0; +assign m_axis_dma_read_desc_ram_addr = dma_read_desc_ram_addr_reg; +assign m_axis_dma_read_desc_len = dma_read_desc_len_reg; +assign m_axis_dma_read_desc_tag = dma_read_desc_tag_reg; +assign m_axis_dma_read_desc_valid = dma_read_desc_valid_reg; + +assign m_axis_dma_write_desc_dma_addr = dma_write_desc_dma_addr_reg; +assign m_axis_dma_write_desc_ram_sel = 0; +assign m_axis_dma_write_desc_ram_addr = dma_write_desc_ram_addr_reg; +assign m_axis_dma_write_desc_len = dma_write_desc_len_reg; +assign m_axis_dma_write_desc_tag = dma_write_desc_tag_reg; +assign m_axis_dma_write_desc_valid = dma_write_desc_valid_reg; + +assign msi_irq[0] = (s_axis_dma_read_desc_status_valid && dma_rd_int_en_reg) || (s_axis_dma_write_desc_status_valid && dma_wr_int_en_reg); +assign msi_irq[31:1] = 31'd0; + +always @* begin + axil_ctrl_awready_next = 1'b0; + axil_ctrl_wready_next = 1'b0; + axil_ctrl_bresp_next = 2'b00; + axil_ctrl_bvalid_next = axil_ctrl_bvalid_reg && !s_axil_ctrl_bready; + axil_ctrl_arready_next = 1'b0; + axil_ctrl_rdata_next = axil_ctrl_rdata_reg; + axil_ctrl_rresp_next = 2'b00; + axil_ctrl_rvalid_next = axil_ctrl_rvalid_reg && !s_axil_ctrl_rready; + + dma_read_desc_dma_addr_next = dma_read_desc_dma_addr_reg; + dma_read_desc_ram_addr_next = dma_read_desc_ram_addr_reg; + dma_read_desc_len_next = dma_read_desc_len_reg; + dma_read_desc_tag_next = dma_read_desc_tag_reg; + dma_read_desc_valid_next = dma_read_desc_valid_reg && !m_axis_dma_read_desc_ready; + + dma_read_desc_status_tag_next = dma_read_desc_status_tag_reg; + dma_read_desc_status_error_next = dma_read_desc_status_error_reg; + dma_read_desc_status_valid_next = dma_read_desc_status_valid_reg; + + dma_write_desc_dma_addr_next = dma_write_desc_dma_addr_reg; + dma_write_desc_ram_addr_next = dma_write_desc_ram_addr_reg; + dma_write_desc_len_next = dma_write_desc_len_reg; + dma_write_desc_tag_next = dma_write_desc_tag_reg; + dma_write_desc_valid_next = dma_write_desc_valid_reg && !m_axis_dma_read_desc_ready; + + dma_write_desc_status_tag_next = dma_write_desc_status_tag_reg; + dma_write_desc_status_error_next = dma_write_desc_status_error_reg; + dma_write_desc_status_valid_next = dma_write_desc_status_valid_reg; + + dma_enable_next = dma_enable_reg; + + dma_rd_int_en_next = dma_rd_int_en_reg; + dma_wr_int_en_next = dma_wr_int_en_reg; + + dma_read_block_run_next = dma_read_block_run_reg; + dma_read_block_len_next = dma_read_block_len_reg; + dma_read_block_count_next = dma_read_block_count_reg; + dma_read_block_cycle_count_next = dma_read_block_cycle_count_reg; + dma_read_block_dma_base_addr_next = dma_read_block_dma_base_addr_reg; + dma_read_block_dma_offset_next = dma_read_block_dma_offset_reg; + dma_read_block_dma_offset_mask_next = dma_read_block_dma_offset_mask_reg; + dma_read_block_dma_stride_next = dma_read_block_dma_stride_reg; + dma_read_block_ram_base_addr_next = dma_read_block_ram_base_addr_reg; + dma_read_block_ram_offset_next = dma_read_block_ram_offset_reg; + dma_read_block_ram_offset_mask_next = dma_read_block_ram_offset_mask_reg; + dma_read_block_ram_stride_next = dma_read_block_ram_stride_reg; + + dma_write_block_run_next = dma_write_block_run_reg; + dma_write_block_len_next = dma_write_block_len_reg; + dma_write_block_count_next = dma_write_block_count_reg; + dma_write_block_cycle_count_next = dma_write_block_cycle_count_reg; + dma_write_block_dma_base_addr_next = dma_write_block_dma_base_addr_reg; + dma_write_block_dma_offset_next = dma_write_block_dma_offset_reg; + dma_write_block_dma_offset_mask_next = dma_write_block_dma_offset_mask_reg; + dma_write_block_dma_stride_next = dma_write_block_dma_stride_reg; + dma_write_block_ram_base_addr_next = dma_write_block_ram_base_addr_reg; + dma_write_block_ram_offset_next = dma_write_block_ram_offset_reg; + dma_write_block_ram_offset_mask_next = dma_write_block_ram_offset_mask_reg; + dma_write_block_ram_stride_next = dma_write_block_ram_stride_reg; + + if (s_axil_ctrl_awvalid && s_axil_ctrl_wvalid && !axil_ctrl_bvalid_reg) begin + // write operation + axil_ctrl_awready_next = 1'b1; + axil_ctrl_wready_next = 1'b1; + axil_ctrl_bresp_next = 2'b00; + axil_ctrl_bvalid_next = 1'b1; + + case ({s_axil_ctrl_awaddr[15:2], 2'b00}) + // control + 16'h0000: begin + dma_enable_next = s_axil_ctrl_wdata[0]; + end + 16'h0008: begin + dma_rd_int_en_next = s_axil_ctrl_wdata[0]; + dma_wr_int_en_next = s_axil_ctrl_wdata[1]; + end + // single read + 16'h0100: dma_read_desc_dma_addr_next[31:0] = s_axil_ctrl_wdata; + 16'h0104: dma_read_desc_dma_addr_next[63:32] = s_axil_ctrl_wdata; + 16'h0108: dma_read_desc_ram_addr_next = s_axil_ctrl_wdata; + 16'h0110: dma_read_desc_len_next = s_axil_ctrl_wdata; + 16'h0114: begin + dma_read_desc_tag_next = s_axil_ctrl_wdata; + dma_read_desc_valid_next = 1'b1; + end + // single write + 16'h0200: dma_write_desc_dma_addr_next[31:0] = s_axil_ctrl_wdata; + 16'h0204: dma_write_desc_dma_addr_next[63:32] = s_axil_ctrl_wdata; + 16'h0208: dma_write_desc_ram_addr_next = s_axil_ctrl_wdata; + 16'h0210: dma_write_desc_len_next = s_axil_ctrl_wdata; + 16'h0214: begin + dma_write_desc_tag_next = s_axil_ctrl_wdata; + dma_write_desc_valid_next = 1'b1; + end + // block read + 16'h1000: begin + dma_read_block_run_next = s_axil_ctrl_wdata[0]; + end + 16'h1008: dma_read_block_cycle_count_next[31:0] = s_axil_ctrl_wdata; + 16'h100c: dma_read_block_cycle_count_next[63:32] = s_axil_ctrl_wdata; + 16'h1010: dma_read_block_len_next = s_axil_ctrl_wdata; + 16'h1018: dma_read_block_count_next[31:0] = s_axil_ctrl_wdata; + 16'h1080: dma_read_block_dma_base_addr_next[31:0] = s_axil_ctrl_wdata; + 16'h1084: dma_read_block_dma_base_addr_next[63:32] = s_axil_ctrl_wdata; + 16'h1088: dma_read_block_dma_offset_next[31:0] = s_axil_ctrl_wdata; + 16'h108c: dma_read_block_dma_offset_next[63:32] = s_axil_ctrl_wdata; + 16'h1090: dma_read_block_dma_offset_mask_next[31:0] = s_axil_ctrl_wdata; + 16'h1094: dma_read_block_dma_offset_mask_next[63:32] = s_axil_ctrl_wdata; + 16'h1098: dma_read_block_dma_stride_next[31:0] = s_axil_ctrl_wdata; + 16'h109c: dma_read_block_dma_stride_next[63:32] = s_axil_ctrl_wdata; + 16'h10c0: dma_read_block_ram_base_addr_next = s_axil_ctrl_wdata; + 16'h10c8: dma_read_block_ram_offset_next = s_axil_ctrl_wdata; + 16'h10d0: dma_read_block_ram_offset_mask_next = s_axil_ctrl_wdata; + 16'h10d8: dma_read_block_ram_stride_next = s_axil_ctrl_wdata; + // block write + 16'h1100: begin + dma_write_block_run_next = s_axil_ctrl_wdata[0]; + end + 16'h1108: dma_write_block_cycle_count_next[31:0] = s_axil_ctrl_wdata; + 16'h110c: dma_write_block_cycle_count_next[63:32] = s_axil_ctrl_wdata; + 16'h1110: dma_write_block_len_next = s_axil_ctrl_wdata; + 16'h1118: dma_write_block_count_next[31:0] = s_axil_ctrl_wdata; + 16'h1180: dma_write_block_dma_base_addr_next[31:0] = s_axil_ctrl_wdata; + 16'h1184: dma_write_block_dma_base_addr_next[63:32] = s_axil_ctrl_wdata; + 16'h1188: dma_write_block_dma_offset_next[31:0] = s_axil_ctrl_wdata; + 16'h118c: dma_write_block_dma_offset_next[63:32] = s_axil_ctrl_wdata; + 16'h1190: dma_write_block_dma_offset_mask_next[31:0] = s_axil_ctrl_wdata; + 16'h1194: dma_write_block_dma_offset_mask_next[63:32] = s_axil_ctrl_wdata; + 16'h1198: dma_write_block_dma_stride_next[31:0] = s_axil_ctrl_wdata; + 16'h119c: dma_write_block_dma_stride_next[63:32] = s_axil_ctrl_wdata; + 16'h11c0: dma_write_block_ram_base_addr_next = s_axil_ctrl_wdata; + 16'h11c8: dma_write_block_ram_offset_next = s_axil_ctrl_wdata; + 16'h11d0: dma_write_block_ram_offset_mask_next = s_axil_ctrl_wdata; + 16'h11d8: dma_write_block_ram_stride_next = s_axil_ctrl_wdata; + endcase + end + + if (s_axil_ctrl_arvalid && !axil_ctrl_rvalid_reg) begin + // read operation + axil_ctrl_arready_next = 1'b1; + axil_ctrl_rresp_next = 2'b00; + axil_ctrl_rvalid_next = 1'b1; + + case ({s_axil_ctrl_araddr[15:2], 2'b00}) + // control + 16'h0000: begin + axil_ctrl_rdata_next[0] = dma_enable_reg; + end + 16'h0008: begin + axil_ctrl_rdata_next[0] = dma_rd_int_en_reg; + axil_ctrl_rdata_next[1] = dma_wr_int_en_reg; + end + 16'h0010: axil_ctrl_rdata_next = cycle_count_reg; + 16'h0014: axil_ctrl_rdata_next = cycle_count_reg >> 32; + 16'h0020: axil_ctrl_rdata_next = dma_read_active_count_reg; + 16'h0028: axil_ctrl_rdata_next = dma_write_active_count_reg; + // single read + 16'h0100: axil_ctrl_rdata_next = dma_read_desc_dma_addr_reg; + 16'h0104: axil_ctrl_rdata_next = dma_read_desc_dma_addr_reg >> 32; + 16'h0108: axil_ctrl_rdata_next = dma_read_desc_ram_addr_reg; + 16'h010c: axil_ctrl_rdata_next = dma_read_desc_ram_addr_reg >> 32; + 16'h0110: axil_ctrl_rdata_next = dma_read_desc_len_reg; + 16'h0114: axil_ctrl_rdata_next = dma_read_desc_tag_reg; + 16'h0118: begin + axil_ctrl_rdata_next[15:0] = dma_read_desc_status_tag_reg; + axil_ctrl_rdata_next[27:24] = dma_read_desc_status_error_reg; + axil_ctrl_rdata_next[31] = dma_read_desc_status_valid_reg; + dma_read_desc_status_valid_next = 1'b0; + end + // single write + 16'h0200: axil_ctrl_rdata_next = dma_write_desc_dma_addr_reg; + 16'h0204: axil_ctrl_rdata_next = dma_write_desc_dma_addr_reg >> 32; + 16'h0208: axil_ctrl_rdata_next = dma_write_desc_ram_addr_reg; + 16'h020c: axil_ctrl_rdata_next = dma_write_desc_ram_addr_reg >> 32; + 16'h0210: axil_ctrl_rdata_next = dma_write_desc_len_reg; + 16'h0214: axil_ctrl_rdata_next = dma_write_desc_tag_reg; + 16'h0218: begin + axil_ctrl_rdata_next[15:0] = dma_write_desc_status_tag_reg; + axil_ctrl_rdata_next[27:24] = dma_write_desc_status_error_reg; + axil_ctrl_rdata_next[31] = dma_write_desc_status_valid_reg; + dma_write_desc_status_valid_next = 1'b0; + end + // block read + 16'h1000: begin + axil_ctrl_rdata_next[0] = dma_read_block_run_reg; + end + 16'h1008: axil_ctrl_rdata_next = dma_read_block_cycle_count_reg; + 16'h100c: axil_ctrl_rdata_next = dma_read_block_cycle_count_reg >> 32; + 16'h1010: axil_ctrl_rdata_next = dma_read_block_len_reg; + 16'h1018: axil_ctrl_rdata_next = dma_read_block_count_reg; + 16'h101c: axil_ctrl_rdata_next = dma_read_block_count_reg >> 32; + 16'h1080: axil_ctrl_rdata_next = dma_read_block_dma_base_addr_reg; + 16'h1084: axil_ctrl_rdata_next = dma_read_block_dma_base_addr_reg >> 32; + 16'h1088: axil_ctrl_rdata_next = dma_read_block_dma_offset_reg; + 16'h108c: axil_ctrl_rdata_next = dma_read_block_dma_offset_reg >> 32; + 16'h1090: axil_ctrl_rdata_next = dma_read_block_dma_offset_mask_reg; + 16'h1094: axil_ctrl_rdata_next = dma_read_block_dma_offset_mask_reg >> 32; + 16'h1098: axil_ctrl_rdata_next = dma_read_block_dma_stride_reg; + 16'h109c: axil_ctrl_rdata_next = dma_read_block_dma_stride_reg >> 32; + 16'h10c0: axil_ctrl_rdata_next = dma_read_block_ram_base_addr_reg; + 16'h10c4: axil_ctrl_rdata_next = dma_read_block_ram_base_addr_reg >> 32; + 16'h10c8: axil_ctrl_rdata_next = dma_read_block_ram_offset_reg; + 16'h10cc: axil_ctrl_rdata_next = dma_read_block_ram_offset_reg >> 32; + 16'h10d0: axil_ctrl_rdata_next = dma_read_block_ram_offset_mask_reg; + 16'h10d4: axil_ctrl_rdata_next = dma_read_block_ram_offset_mask_reg >> 32; + 16'h10d8: axil_ctrl_rdata_next = dma_read_block_ram_stride_reg; + 16'h10dc: axil_ctrl_rdata_next = dma_read_block_ram_stride_reg >> 32; + // block write + 16'h1100: begin + axil_ctrl_rdata_next[0] = dma_write_block_run_reg; + end + 16'h1108: axil_ctrl_rdata_next = dma_write_block_cycle_count_reg; + 16'h110c: axil_ctrl_rdata_next = dma_write_block_cycle_count_reg >> 32; + 16'h1110: axil_ctrl_rdata_next = dma_write_block_len_reg; + 16'h1118: axil_ctrl_rdata_next = dma_write_block_count_reg; + 16'h111c: axil_ctrl_rdata_next = dma_write_block_count_reg >> 32; + 16'h1180: axil_ctrl_rdata_next = dma_write_block_dma_base_addr_reg; + 16'h1184: axil_ctrl_rdata_next = dma_write_block_dma_base_addr_reg >> 32; + 16'h1188: axil_ctrl_rdata_next = dma_write_block_dma_offset_reg; + 16'h118c: axil_ctrl_rdata_next = dma_write_block_dma_offset_reg >> 32; + 16'h1190: axil_ctrl_rdata_next = dma_write_block_dma_offset_mask_reg; + 16'h1194: axil_ctrl_rdata_next = dma_write_block_dma_offset_mask_reg >> 32; + 16'h1198: axil_ctrl_rdata_next = dma_write_block_dma_stride_reg; + 16'h119c: axil_ctrl_rdata_next = dma_write_block_dma_stride_reg >> 32; + 16'h11c0: axil_ctrl_rdata_next = dma_write_block_ram_base_addr_reg; + 16'h11c4: axil_ctrl_rdata_next = dma_write_block_ram_base_addr_reg >> 32; + 16'h11c8: axil_ctrl_rdata_next = dma_write_block_ram_offset_reg; + 16'h11cc: axil_ctrl_rdata_next = dma_write_block_ram_offset_reg >> 32; + 16'h11d0: axil_ctrl_rdata_next = dma_write_block_ram_offset_mask_reg; + 16'h11d4: axil_ctrl_rdata_next = dma_write_block_ram_offset_mask_reg >> 32; + 16'h11d8: axil_ctrl_rdata_next = dma_write_block_ram_stride_reg; + 16'h11dc: axil_ctrl_rdata_next = dma_write_block_ram_stride_reg >> 32; + endcase + end + + // store read response + if (s_axis_dma_read_desc_status_valid) begin + dma_read_desc_status_tag_next = s_axis_dma_read_desc_status_tag; + dma_read_desc_status_error_next = s_axis_dma_read_desc_status_error; + dma_read_desc_status_valid_next = s_axis_dma_read_desc_status_valid; + end + + // store write response + if (s_axis_dma_write_desc_status_valid) begin + dma_write_desc_status_tag_next = s_axis_dma_write_desc_status_tag; + dma_write_desc_status_error_next = s_axis_dma_write_desc_status_error; + dma_write_desc_status_valid_next = s_axis_dma_write_desc_status_valid; + end + + // block read + if (dma_read_block_run_reg) begin + dma_read_block_cycle_count_next = dma_read_block_cycle_count_reg + 1; + + if (dma_read_block_count_reg == 0) begin + if (dma_read_active_count_reg == 0) begin + dma_read_block_run_next = 1'b0; + end + end else begin + if (!dma_read_desc_valid_reg || m_axis_dma_read_desc_ready) begin + dma_read_block_dma_offset_next = dma_read_block_dma_offset_reg + dma_read_block_dma_stride_reg; + dma_read_desc_dma_addr_next = dma_read_block_dma_base_addr_reg + (dma_read_block_dma_offset_reg & dma_read_block_dma_offset_mask_reg); + dma_read_block_ram_offset_next = dma_read_block_ram_offset_reg + dma_read_block_ram_stride_reg; + dma_read_desc_ram_addr_next = dma_read_block_ram_base_addr_reg + (dma_read_block_ram_offset_reg & dma_read_block_ram_offset_mask_reg); + dma_read_desc_len_next = dma_read_block_len_reg; + dma_read_block_count_next = dma_read_block_count_reg - 1; + dma_read_desc_tag_next = dma_read_block_count_reg; + dma_read_desc_valid_next = 1'b1; + end + end + end + + // block write + if (dma_write_block_run_reg) begin + dma_write_block_cycle_count_next = dma_write_block_cycle_count_reg + 1; + + if (dma_write_block_count_reg == 0) begin + if (dma_write_active_count_reg == 0) begin + dma_write_block_run_next = 1'b0; + end + end else begin + if (!dma_write_desc_valid_reg || m_axis_dma_write_desc_ready) begin + dma_write_block_dma_offset_next = dma_write_block_dma_offset_reg + dma_write_block_dma_stride_reg; + dma_write_desc_dma_addr_next = dma_write_block_dma_base_addr_reg + (dma_write_block_dma_offset_reg & dma_write_block_dma_offset_mask_reg); + dma_write_block_ram_offset_next = dma_write_block_ram_offset_reg + dma_write_block_ram_stride_reg; + dma_write_desc_ram_addr_next = dma_write_block_ram_base_addr_reg + (dma_write_block_ram_offset_reg & dma_write_block_ram_offset_mask_reg); + dma_write_desc_len_next = dma_write_block_len_reg; + dma_write_block_count_next = dma_write_block_count_reg - 1; + dma_write_desc_tag_next = dma_write_block_count_reg; + dma_write_desc_valid_next = 1'b1; + end + end + end +end + +always @(posedge clk) begin + axil_ctrl_awready_reg <= axil_ctrl_awready_next; + axil_ctrl_wready_reg <= axil_ctrl_wready_next; + axil_ctrl_bresp_reg <= axil_ctrl_bresp_next; + axil_ctrl_bvalid_reg <= axil_ctrl_bvalid_next; + axil_ctrl_arready_reg <= axil_ctrl_arready_next; + axil_ctrl_rdata_reg <= axil_ctrl_rdata_next; + axil_ctrl_rresp_reg <= axil_ctrl_rresp_next; + axil_ctrl_rvalid_reg <= axil_ctrl_rvalid_next; + + cycle_count_reg <= cycle_count_reg + 1; + + dma_read_active_count_reg <= dma_read_active_count_reg + + (m_axis_dma_read_desc_valid && m_axis_dma_read_desc_ready) + - s_axis_dma_read_desc_status_valid; + dma_write_active_count_reg <= dma_write_active_count_reg + + (m_axis_dma_write_desc_valid && m_axis_dma_write_desc_ready) + - s_axis_dma_write_desc_status_valid; + + dma_read_desc_dma_addr_reg <= dma_read_desc_dma_addr_next; + dma_read_desc_ram_addr_reg <= dma_read_desc_ram_addr_next; + dma_read_desc_len_reg <= dma_read_desc_len_next; + dma_read_desc_tag_reg <= dma_read_desc_tag_next; + dma_read_desc_valid_reg <= dma_read_desc_valid_next; + + dma_read_desc_status_tag_reg <= dma_read_desc_status_tag_next; + dma_read_desc_status_error_reg <= dma_read_desc_status_error_next; + dma_read_desc_status_valid_reg <= dma_read_desc_status_valid_next; + + dma_write_desc_dma_addr_reg <= dma_write_desc_dma_addr_next; + dma_write_desc_ram_addr_reg <= dma_write_desc_ram_addr_next; + dma_write_desc_len_reg <= dma_write_desc_len_next; + dma_write_desc_tag_reg <= dma_write_desc_tag_next; + dma_write_desc_valid_reg <= dma_write_desc_valid_next; + + dma_write_desc_status_tag_reg <= dma_write_desc_status_tag_next; + dma_write_desc_status_error_reg <= dma_write_desc_status_error_next; + dma_write_desc_status_valid_reg <= dma_write_desc_status_valid_next; + + dma_enable_reg <= dma_enable_next; + + dma_rd_int_en_reg <= dma_rd_int_en_next; + dma_wr_int_en_reg <= dma_wr_int_en_next; + + dma_read_block_run_reg <= dma_read_block_run_next; + dma_read_block_len_reg <= dma_read_block_len_next; + dma_read_block_count_reg <= dma_read_block_count_next; + dma_read_block_cycle_count_reg <= dma_read_block_cycle_count_next; + dma_read_block_dma_base_addr_reg <= dma_read_block_dma_base_addr_next; + dma_read_block_dma_offset_reg <= dma_read_block_dma_offset_next; + dma_read_block_dma_offset_mask_reg <= dma_read_block_dma_offset_mask_next; + dma_read_block_dma_stride_reg <= dma_read_block_dma_stride_next; + dma_read_block_ram_base_addr_reg <= dma_read_block_ram_base_addr_next; + dma_read_block_ram_offset_reg <= dma_read_block_ram_offset_next; + dma_read_block_ram_offset_mask_reg <= dma_read_block_ram_offset_mask_next; + dma_read_block_ram_stride_reg <= dma_read_block_ram_stride_next; + + dma_write_block_run_reg <= dma_write_block_run_next; + dma_write_block_len_reg <= dma_write_block_len_next; + dma_write_block_count_reg <= dma_write_block_count_next; + dma_write_block_cycle_count_reg <= dma_write_block_cycle_count_next; + dma_write_block_dma_base_addr_reg <= dma_write_block_dma_base_addr_next; + dma_write_block_dma_offset_reg <= dma_write_block_dma_offset_next; + dma_write_block_dma_offset_mask_reg <= dma_write_block_dma_offset_mask_next; + dma_write_block_dma_stride_reg <= dma_write_block_dma_stride_next; + dma_write_block_ram_base_addr_reg <= dma_write_block_ram_base_addr_next; + dma_write_block_ram_offset_reg <= dma_write_block_ram_offset_next; + dma_write_block_ram_offset_mask_reg <= dma_write_block_ram_offset_mask_next; + dma_write_block_ram_stride_reg <= dma_write_block_ram_stride_next; + + if (rst) begin + axil_ctrl_awready_reg <= 1'b0; + axil_ctrl_wready_reg <= 1'b0; + axil_ctrl_bvalid_reg <= 1'b0; + axil_ctrl_arready_reg <= 1'b0; + axil_ctrl_rvalid_reg <= 1'b0; + + cycle_count_reg <= 0; + dma_read_active_count_reg <= 0; + dma_write_active_count_reg <= 0; + + dma_read_desc_valid_reg <= 1'b0; + dma_read_desc_status_valid_reg <= 1'b0; + dma_write_desc_valid_reg <= 1'b0; + dma_write_desc_status_valid_reg <= 1'b0; + dma_enable_reg <= 1'b0; + dma_rd_int_en_reg <= 1'b0; + dma_wr_int_en_reg <= 1'b0; + dma_read_block_run_reg <= 1'b0; + dma_write_block_run_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/common/rtl/example_core_pcie.v b/fpga/lib/pcie/example/common/rtl/example_core_pcie.v new file mode 100644 index 000000000..0e4acc3d0 --- /dev/null +++ b/fpga/lib/pcie/example/common/rtl/example_core_pcie.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Example design core logic - PCIe DMA wrapper + */ +module example_core_pcie # +( + // TLP segment count + parameter TLP_SEG_COUNT = 1, + // TLP segment data width + parameter TLP_SEG_DATA_WIDTH = 256, + // TLP segment strobe width + parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32, + // TLP segment header width + parameter TLP_SEG_HDR_WIDTH = 128, + // TX sequence number count + parameter TX_SEQ_NUM_COUNT = 1, + // TX sequence number width + parameter TX_SEQ_NUM_WIDTH = 5, + // TX sequence number tracking enable + parameter TX_SEQ_NUM_ENABLE = 1, + // PCIe tag count + parameter PCIE_TAG_COUNT = 256, + // Operation table size (read) + parameter READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + // In-flight transmit limit (read) + parameter READ_TX_LIMIT = 2**TX_SEQ_NUM_WIDTH, + // Transmit flow control (read) + parameter READ_TX_FC_ENABLE = 1, + // Operation table size (write) + parameter WRITE_OP_TABLE_SIZE = 2**TX_SEQ_NUM_WIDTH, + // In-flight transmit limit (write) + parameter WRITE_TX_LIMIT = 2**TX_SEQ_NUM_WIDTH, + // Transmit flow control (write) + parameter WRITE_TX_FC_ENABLE = 1, + // Force 64 bit address + parameter TLP_FORCE_64_BIT_ADDR = 0, + // Requester ID mash + parameter CHECK_BUS_NUMBER = 1, + // BAR0 aperture (log2 size) + parameter BAR0_APERTURE = 24, + // BAR2 aperture (log2 size) + parameter BAR2_APERTURE = 24 +) +( + input wire clk, + input wire rst, + + /* + * TLP input (request) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_req_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_req_tlp_hdr, + input wire [TLP_SEG_COUNT*3-1:0] rx_req_tlp_bar_id, + input wire [TLP_SEG_COUNT*8-1:0] rx_req_tlp_func_num, + input wire [TLP_SEG_COUNT-1:0] rx_req_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] rx_req_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] rx_req_tlp_eop, + output wire rx_req_tlp_ready, + + /* + * TLP output (completion) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_cpl_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_cpl_tlp_strb, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_cpl_tlp_hdr, + output wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_eop, + input wire tx_cpl_tlp_ready, + + /* + * TLP input (completion) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_cpl_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_cpl_tlp_hdr, + input wire [TLP_SEG_COUNT*4-1:0] rx_cpl_tlp_error, + input wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_eop, + output wire rx_cpl_tlp_ready, + + /* + * TLP output (read request) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_rd_req_tlp_hdr, + output wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_rd_req_tlp_seq, + output wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_eop, + input wire tx_rd_req_tlp_ready, + + /* + * TLP output (write request) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_wr_req_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_wr_req_tlp_strb, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_wr_req_tlp_hdr, + output wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_wr_req_tlp_seq, + output wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_eop, + input wire tx_wr_req_tlp_ready, + + /* + * Transmit sequence number input + */ + input wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] s_axis_rd_req_tx_seq_num, + input wire [TX_SEQ_NUM_COUNT-1:0] s_axis_rd_req_tx_seq_num_valid, + input wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] s_axis_wr_req_tx_seq_num, + input wire [TX_SEQ_NUM_COUNT-1:0] s_axis_wr_req_tx_seq_num_valid, + + /* + * Transmit flow control + */ + input wire [7:0] pcie_tx_fc_ph_av, + input wire [11:0] pcie_tx_fc_pd_av, + input wire [7:0] pcie_tx_fc_nph_av, + + /* + * Configuration + */ + input wire [7:0] bus_num, + input wire ext_tag_enable, + input wire [2:0] max_read_request_size, + input wire [2:0] max_payload_size, + + /* + * Status + */ + output wire status_error_cor, + output wire status_error_uncor, + + /* + * MSI request outputs + */ + output wire [31:0] msi_irq +); + +parameter AXIL_DATA_WIDTH = 32; +parameter AXIL_ADDR_WIDTH = BAR0_APERTURE; +parameter AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8); + +parameter AXI_DATA_WIDTH = TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH; +parameter AXI_STRB_WIDTH = (AXI_DATA_WIDTH/8); +parameter AXI_ADDR_WIDTH = BAR2_APERTURE; +parameter AXI_ID_WIDTH = 8; + +parameter RAM_SEG_COUNT = TLP_SEG_COUNT*2; +parameter RAM_SEG_DATA_WIDTH = (TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH)*2/RAM_SEG_COUNT; +parameter RAM_SEG_ADDR_WIDTH = 10; +parameter RAM_SEG_BE_WIDTH = RAM_SEG_DATA_WIDTH/8; +parameter RAM_SEL_WIDTH = 2; +parameter RAM_ADDR_WIDTH = RAM_SEG_ADDR_WIDTH+$clog2(RAM_SEG_COUNT)+$clog2(RAM_SEG_BE_WIDTH); + +parameter PCIE_ADDR_WIDTH = 64; +parameter DMA_LEN_WIDTH = 16; +parameter DMA_TAG_WIDTH = 8; + +wire [AXIL_ADDR_WIDTH-1:0] axil_ctrl_awaddr; +wire [2:0] axil_ctrl_awprot; +wire axil_ctrl_awvalid; +wire axil_ctrl_awready; +wire [AXIL_DATA_WIDTH-1:0] axil_ctrl_wdata; +wire [AXIL_STRB_WIDTH-1:0] axil_ctrl_wstrb; +wire axil_ctrl_wvalid; +wire axil_ctrl_wready; +wire [1:0] axil_ctrl_bresp; +wire axil_ctrl_bvalid; +wire axil_ctrl_bready; +wire [AXIL_ADDR_WIDTH-1:0] axil_ctrl_araddr; +wire [2:0] axil_ctrl_arprot; +wire axil_ctrl_arvalid; +wire axil_ctrl_arready; +wire [AXIL_DATA_WIDTH-1:0] axil_ctrl_rdata; +wire [1:0] axil_ctrl_rresp; +wire axil_ctrl_rvalid; +wire axil_ctrl_rready; + +wire [PCIE_ADDR_WIDTH-1:0] axis_dma_read_desc_dma_addr; +wire [RAM_SEL_WIDTH-1:0] axis_dma_read_desc_ram_sel; +wire [RAM_ADDR_WIDTH-1:0] axis_dma_read_desc_ram_addr; +wire [DMA_LEN_WIDTH-1:0] axis_dma_read_desc_len; +wire [DMA_TAG_WIDTH-1:0] axis_dma_read_desc_tag; +wire axis_dma_read_desc_valid; +wire axis_dma_read_desc_ready; + +wire [DMA_TAG_WIDTH-1:0] axis_dma_read_desc_status_tag; +wire [3:0] axis_dma_read_desc_status_error; +wire axis_dma_read_desc_status_valid; + +wire [PCIE_ADDR_WIDTH-1:0] axis_dma_write_desc_dma_addr; +wire [RAM_SEL_WIDTH-1:0] axis_dma_write_desc_ram_sel; +wire [RAM_ADDR_WIDTH-1:0] axis_dma_write_desc_ram_addr; +wire [DMA_LEN_WIDTH-1:0] axis_dma_write_desc_len; +wire [DMA_TAG_WIDTH-1:0] axis_dma_write_desc_tag; +wire axis_dma_write_desc_valid; +wire axis_dma_write_desc_ready; + +wire [DMA_TAG_WIDTH-1:0] axis_dma_write_desc_status_tag; +wire [3:0] axis_dma_write_desc_status_error; +wire axis_dma_write_desc_status_valid; + +wire [RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel; +wire [RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0] ram_rd_cmd_addr; +wire [RAM_SEG_COUNT-1:0] ram_rd_cmd_valid; +wire [RAM_SEG_COUNT-1:0] ram_rd_cmd_ready; +wire [RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-1:0] ram_rd_resp_data; +wire [RAM_SEG_COUNT-1:0] ram_rd_resp_valid; +wire [RAM_SEG_COUNT-1:0] ram_rd_resp_ready; +wire [RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0] ram_wr_cmd_sel; +wire [RAM_SEG_COUNT*RAM_SEG_BE_WIDTH-1:0] ram_wr_cmd_be; +wire [RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0] ram_wr_cmd_addr; +wire [RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-1:0] ram_wr_cmd_data; +wire [RAM_SEG_COUNT-1:0] ram_wr_cmd_valid; +wire [RAM_SEG_COUNT-1:0] ram_wr_cmd_ready; +wire [RAM_SEG_COUNT-1:0] ram_wr_done; + +wire [2:0] status_error_cor_int; +wire [2:0] status_error_uncor_int; + +// PCIe connections +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] ctrl_rx_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] ctrl_rx_req_tlp_hdr; +wire [TLP_SEG_COUNT*3-1:0] ctrl_rx_req_tlp_bar_id; +wire [TLP_SEG_COUNT*8-1:0] ctrl_rx_req_tlp_func_num; +wire [TLP_SEG_COUNT-1:0] ctrl_rx_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] ctrl_rx_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] ctrl_rx_req_tlp_eop; +wire ctrl_rx_req_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] ctrl_tx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] ctrl_tx_cpl_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] ctrl_tx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT-1:0] ctrl_tx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] ctrl_tx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] ctrl_tx_cpl_tlp_eop; +wire ctrl_tx_cpl_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] ram_rx_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] ram_rx_req_tlp_hdr; +wire [TLP_SEG_COUNT*3-1:0] ram_rx_req_tlp_bar_id; +wire [TLP_SEG_COUNT*8-1:0] ram_rx_req_tlp_func_num; +wire [TLP_SEG_COUNT-1:0] ram_rx_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] ram_rx_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] ram_rx_req_tlp_eop; +wire ram_rx_req_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] ram_tx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] ram_tx_cpl_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] ram_tx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT-1:0] ram_tx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] ram_tx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] ram_tx_cpl_tlp_eop; +wire ram_tx_cpl_tlp_ready; + +pcie_tlp_demux_bar #( + .PORTS(2), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .BAR_BASE(0), + .BAR_STRIDE(2), + .BAR_IDS(0) +) +pcie_tlp_demux_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input + */ + .in_tlp_data(rx_req_tlp_data), + .in_tlp_strb(0), + .in_tlp_hdr(rx_req_tlp_hdr), + .in_tlp_bar_id(rx_req_tlp_bar_id), + .in_tlp_func_num(rx_req_tlp_func_num), + .in_tlp_error(0), + .in_tlp_valid(rx_req_tlp_valid), + .in_tlp_sop(rx_req_tlp_sop), + .in_tlp_eop(rx_req_tlp_eop), + .in_tlp_ready(rx_req_tlp_ready), + + /* + * TLP output + */ + .out_tlp_data( {ram_rx_req_tlp_data, ctrl_rx_req_tlp_data }), + .out_tlp_strb(), + .out_tlp_hdr( {ram_rx_req_tlp_hdr, ctrl_rx_req_tlp_hdr }), + .out_tlp_bar_id( {ram_rx_req_tlp_bar_id, ctrl_rx_req_tlp_bar_id }), + .out_tlp_func_num({ram_rx_req_tlp_func_num, ctrl_rx_req_tlp_func_num}), + .out_tlp_error(), + .out_tlp_valid( {ram_rx_req_tlp_valid, ctrl_rx_req_tlp_valid }), + .out_tlp_sop( {ram_rx_req_tlp_sop, ctrl_rx_req_tlp_sop }), + .out_tlp_eop( {ram_rx_req_tlp_eop, ctrl_rx_req_tlp_eop }), + .out_tlp_ready( {ram_rx_req_tlp_ready, ctrl_rx_req_tlp_ready }), + + /* + * Control + */ + .enable(1'b1) +); + +pcie_tlp_mux #( + .PORTS(2), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .ARB_TYPE_ROUND_ROBIN(1), + .ARB_LSB_HIGH_PRIORITY(1) +) +pcie_tlp_mux_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input + */ + .in_tlp_data( {ram_tx_cpl_tlp_data, ctrl_tx_cpl_tlp_data }), + .in_tlp_strb( {ram_tx_cpl_tlp_strb, ctrl_tx_cpl_tlp_strb }), + .in_tlp_hdr( {ram_tx_cpl_tlp_hdr, ctrl_tx_cpl_tlp_hdr }), + .in_tlp_bar_id(0), + .in_tlp_func_num(0), + .in_tlp_error(0), + .in_tlp_valid({ram_tx_cpl_tlp_valid, ctrl_tx_cpl_tlp_valid}), + .in_tlp_sop( {ram_tx_cpl_tlp_sop, ctrl_tx_cpl_tlp_sop }), + .in_tlp_eop( {ram_tx_cpl_tlp_eop, ctrl_tx_cpl_tlp_eop }), + .in_tlp_ready({ram_tx_cpl_tlp_ready, ctrl_tx_cpl_tlp_ready}), + + /* + * TLP output + */ + .out_tlp_data(tx_cpl_tlp_data), + .out_tlp_strb(tx_cpl_tlp_strb), + .out_tlp_hdr(tx_cpl_tlp_hdr), + .out_tlp_bar_id(), + .out_tlp_func_num(), + .out_tlp_error(), + .out_tlp_valid(tx_cpl_tlp_valid), + .out_tlp_sop(tx_cpl_tlp_sop), + .out_tlp_eop(tx_cpl_tlp_eop), + .out_tlp_ready(tx_cpl_tlp_ready) +); + +pcie_axil_master #( + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .AXIL_DATA_WIDTH(AXIL_DATA_WIDTH), + .AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH), + .AXIL_STRB_WIDTH(AXIL_STRB_WIDTH), + .TLP_FORCE_64_BIT_ADDR(TLP_FORCE_64_BIT_ADDR) +) +pcie_axil_master_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input (request) + */ + .rx_req_tlp_data(ctrl_rx_req_tlp_data), + .rx_req_tlp_hdr(ctrl_rx_req_tlp_hdr), + .rx_req_tlp_valid(ctrl_rx_req_tlp_valid), + .rx_req_tlp_sop(ctrl_rx_req_tlp_sop), + .rx_req_tlp_eop(ctrl_rx_req_tlp_eop), + .rx_req_tlp_ready(ctrl_rx_req_tlp_ready), + + /* + * TLP output (completion) + */ + .tx_cpl_tlp_data(ctrl_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(ctrl_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(ctrl_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(ctrl_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(ctrl_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(ctrl_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(ctrl_tx_cpl_tlp_ready), + + /* + * AXI Lite Master output + */ + .m_axil_awaddr(axil_ctrl_awaddr), + .m_axil_awprot(axil_ctrl_awprot), + .m_axil_awvalid(axil_ctrl_awvalid), + .m_axil_awready(axil_ctrl_awready), + .m_axil_wdata(axil_ctrl_wdata), + .m_axil_wstrb(axil_ctrl_wstrb), + .m_axil_wvalid(axil_ctrl_wvalid), + .m_axil_wready(axil_ctrl_wready), + .m_axil_bresp(axil_ctrl_bresp), + .m_axil_bvalid(axil_ctrl_bvalid), + .m_axil_bready(axil_ctrl_bready), + .m_axil_araddr(axil_ctrl_araddr), + .m_axil_arprot(axil_ctrl_arprot), + .m_axil_arvalid(axil_ctrl_arvalid), + .m_axil_arready(axil_ctrl_arready), + .m_axil_rdata(axil_ctrl_rdata), + .m_axil_rresp(axil_ctrl_rresp), + .m_axil_rvalid(axil_ctrl_rvalid), + .m_axil_rready(axil_ctrl_rready), + + /* + * Configuration + */ + .completer_id({bus_num, 5'd0, 3'd0}), + + /* + * Status + */ + .status_error_cor(status_error_cor_int[0]), + .status_error_uncor(status_error_uncor_int[0]) +); + +wire [AXI_ID_WIDTH-1:0] axi_ram_awid; +wire [AXI_ADDR_WIDTH-1:0] axi_ram_awaddr; +wire [7:0] axi_ram_awlen; +wire [2:0] axi_ram_awsize; +wire [1:0] axi_ram_awburst; +wire axi_ram_awlock; +wire [3:0] axi_ram_awcache; +wire [2:0] axi_ram_awprot; +wire axi_ram_awvalid; +wire axi_ram_awready; +wire [AXI_DATA_WIDTH-1:0] axi_ram_wdata; +wire [AXI_STRB_WIDTH-1:0] axi_ram_wstrb; +wire axi_ram_wlast; +wire axi_ram_wvalid; +wire axi_ram_wready; +wire [AXI_ID_WIDTH-1:0] axi_ram_bid; +wire [1:0] axi_ram_bresp; +wire axi_ram_bvalid; +wire axi_ram_bready; +wire [AXI_ID_WIDTH-1:0] axi_ram_arid; +wire [AXI_ADDR_WIDTH-1:0] axi_ram_araddr; +wire [7:0] axi_ram_arlen; +wire [2:0] axi_ram_arsize; +wire [1:0] axi_ram_arburst; +wire axi_ram_arlock; +wire [3:0] axi_ram_arcache; +wire [2:0] axi_ram_arprot; +wire axi_ram_arvalid; +wire axi_ram_arready; +wire [AXI_ID_WIDTH-1:0] axi_ram_rid; +wire [AXI_DATA_WIDTH-1:0] axi_ram_rdata; +wire [1:0] axi_ram_rresp; +wire axi_ram_rlast; +wire axi_ram_rvalid; +wire axi_ram_rready; + +pcie_axi_master #( + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .AXI_DATA_WIDTH(AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH(AXI_STRB_WIDTH), + .AXI_ID_WIDTH(AXI_ID_WIDTH), + .AXI_MAX_BURST_LEN(256), + .TLP_FORCE_64_BIT_ADDR(TLP_FORCE_64_BIT_ADDR) +) +pcie_axi_master_isnt ( + .clk(clk), + .rst(rst), + + /* + * TLP input (request) + */ + .rx_req_tlp_data(ram_rx_req_tlp_data), + .rx_req_tlp_hdr(ram_rx_req_tlp_hdr), + .rx_req_tlp_valid(ram_rx_req_tlp_valid), + .rx_req_tlp_sop(ram_rx_req_tlp_sop), + .rx_req_tlp_eop(ram_rx_req_tlp_eop), + .rx_req_tlp_ready(ram_rx_req_tlp_ready), + + /* + * TLP output (completion) + */ + .tx_cpl_tlp_data(ram_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(ram_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(ram_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(ram_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(ram_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(ram_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(ram_tx_cpl_tlp_ready), + + /* + * AXI Master output + */ + .m_axi_awid(axi_ram_awid), + .m_axi_awaddr(axi_ram_awaddr), + .m_axi_awlen(axi_ram_awlen), + .m_axi_awsize(axi_ram_awsize), + .m_axi_awburst(axi_ram_awburst), + .m_axi_awlock(axi_ram_awlock), + .m_axi_awcache(axi_ram_awcache), + .m_axi_awprot(axi_ram_awprot), + .m_axi_awvalid(axi_ram_awvalid), + .m_axi_awready(axi_ram_awready), + .m_axi_wdata(axi_ram_wdata), + .m_axi_wstrb(axi_ram_wstrb), + .m_axi_wlast(axi_ram_wlast), + .m_axi_wvalid(axi_ram_wvalid), + .m_axi_wready(axi_ram_wready), + .m_axi_bid(axi_ram_bid), + .m_axi_bresp(axi_ram_bresp), + .m_axi_bvalid(axi_ram_bvalid), + .m_axi_bready(axi_ram_bready), + .m_axi_arid(axi_ram_arid), + .m_axi_araddr(axi_ram_araddr), + .m_axi_arlen(axi_ram_arlen), + .m_axi_arsize(axi_ram_arsize), + .m_axi_arburst(axi_ram_arburst), + .m_axi_arlock(axi_ram_arlock), + .m_axi_arcache(axi_ram_arcache), + .m_axi_arprot(axi_ram_arprot), + .m_axi_arvalid(axi_ram_arvalid), + .m_axi_arready(axi_ram_arready), + .m_axi_rid(axi_ram_rid), + .m_axi_rdata(axi_ram_rdata), + .m_axi_rresp(axi_ram_rresp), + .m_axi_rlast(axi_ram_rlast), + .m_axi_rvalid(axi_ram_rvalid), + .m_axi_rready(axi_ram_rready), + + /* + * Configuration + */ + .completer_id({bus_num, 5'd0, 3'd0}), + .max_payload_size(max_payload_size), + + /* + * Status + */ + .status_error_cor(status_error_cor_int[1]), + .status_error_uncor(status_error_uncor_int[1]) +); + +axi_ram #( + .DATA_WIDTH(AXI_DATA_WIDTH), + .ADDR_WIDTH(AXI_ADDR_WIDTH < 16 ? AXI_ADDR_WIDTH : 16), + .ID_WIDTH(AXI_ID_WIDTH), + .PIPELINE_OUTPUT(1) +) +axi_ram_inst ( + .clk(clk), + .rst(rst), + .s_axi_awid(axi_ram_awid), + .s_axi_awaddr(axi_ram_awaddr), + .s_axi_awlen(axi_ram_awlen), + .s_axi_awsize(axi_ram_awsize), + .s_axi_awburst(axi_ram_awburst), + .s_axi_awlock(axi_ram_awlock), + .s_axi_awcache(axi_ram_awcache), + .s_axi_awprot(axi_ram_awprot), + .s_axi_awvalid(axi_ram_awvalid), + .s_axi_awready(axi_ram_awready), + .s_axi_wdata(axi_ram_wdata), + .s_axi_wstrb(axi_ram_wstrb), + .s_axi_wlast(axi_ram_wlast), + .s_axi_wvalid(axi_ram_wvalid), + .s_axi_wready(axi_ram_wready), + .s_axi_bid(axi_ram_bid), + .s_axi_bresp(axi_ram_bresp), + .s_axi_bvalid(axi_ram_bvalid), + .s_axi_bready(axi_ram_bready), + .s_axi_arid(axi_ram_arid), + .s_axi_araddr(axi_ram_araddr), + .s_axi_arlen(axi_ram_arlen), + .s_axi_arsize(axi_ram_arsize), + .s_axi_arburst(axi_ram_arburst), + .s_axi_arlock(axi_ram_arlock), + .s_axi_arcache(axi_ram_arcache), + .s_axi_arprot(axi_ram_arprot), + .s_axi_arvalid(axi_ram_arvalid), + .s_axi_arready(axi_ram_arready), + .s_axi_rid(axi_ram_rid), + .s_axi_rdata(axi_ram_rdata), + .s_axi_rresp(axi_ram_rresp), + .s_axi_rlast(axi_ram_rlast), + .s_axi_rvalid(axi_ram_rvalid), + .s_axi_rready(axi_ram_rready) +); + +dma_if_pcie #( + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .TX_SEQ_NUM_ENABLE(TX_SEQ_NUM_ENABLE), + .RAM_SEG_COUNT(RAM_SEG_COUNT), + .RAM_SEG_DATA_WIDTH(RAM_SEG_DATA_WIDTH), + .RAM_SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH), + .RAM_SEG_BE_WIDTH(RAM_SEG_BE_WIDTH), + .RAM_SEL_WIDTH(RAM_SEL_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), + .PCIE_ADDR_WIDTH(PCIE_ADDR_WIDTH), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .LEN_WIDTH(DMA_LEN_WIDTH), + .TAG_WIDTH(DMA_TAG_WIDTH), + .READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE), + .READ_TX_LIMIT(READ_TX_LIMIT), + .READ_TX_FC_ENABLE(READ_TX_FC_ENABLE), + .WRITE_OP_TABLE_SIZE(WRITE_OP_TABLE_SIZE), + .WRITE_TX_LIMIT(WRITE_TX_LIMIT), + .WRITE_TX_FC_ENABLE(WRITE_TX_FC_ENABLE), + .TLP_FORCE_64_BIT_ADDR(TLP_FORCE_64_BIT_ADDR), + .CHECK_BUS_NUMBER(CHECK_BUS_NUMBER) +) +dma_if_pcie_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input (completion) + */ + .rx_cpl_tlp_data(rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(rx_cpl_tlp_error), + .rx_cpl_tlp_valid(rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(rx_cpl_tlp_ready), + + /* + * TLP output (read request) + */ + .tx_rd_req_tlp_hdr(tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(tx_rd_req_tlp_ready), + + /* + * TLP output (write request) + */ + .tx_wr_req_tlp_data(tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(tx_wr_req_tlp_ready), + + /* + * Transmit sequence number input + */ + .s_axis_rd_req_tx_seq_num(s_axis_rd_req_tx_seq_num), + .s_axis_rd_req_tx_seq_num_valid(s_axis_rd_req_tx_seq_num_valid), + .s_axis_wr_req_tx_seq_num(s_axis_wr_req_tx_seq_num), + .s_axis_wr_req_tx_seq_num_valid(s_axis_wr_req_tx_seq_num_valid), + + /* + * Transmit flow control + */ + .pcie_tx_fc_ph_av(pcie_tx_fc_ph_av), + .pcie_tx_fc_pd_av(pcie_tx_fc_pd_av), + .pcie_tx_fc_nph_av(pcie_tx_fc_nph_av), + + /* + * AXI read descriptor input + */ + .s_axis_read_desc_pcie_addr(axis_dma_read_desc_dma_addr), + .s_axis_read_desc_ram_sel(axis_dma_read_desc_ram_sel), + .s_axis_read_desc_ram_addr(axis_dma_read_desc_ram_addr), + .s_axis_read_desc_len(axis_dma_read_desc_len), + .s_axis_read_desc_tag(axis_dma_read_desc_tag), + .s_axis_read_desc_valid(axis_dma_read_desc_valid), + .s_axis_read_desc_ready(axis_dma_read_desc_ready), + + /* + * AXI read descriptor status output + */ + .m_axis_read_desc_status_tag(axis_dma_read_desc_status_tag), + .m_axis_read_desc_status_error(axis_dma_read_desc_status_error), + .m_axis_read_desc_status_valid(axis_dma_read_desc_status_valid), + + /* + * AXI write descriptor input + */ + .s_axis_write_desc_pcie_addr(axis_dma_write_desc_dma_addr), + .s_axis_write_desc_ram_sel(axis_dma_write_desc_ram_sel), + .s_axis_write_desc_ram_addr(axis_dma_write_desc_ram_addr), + .s_axis_write_desc_len(axis_dma_write_desc_len), + .s_axis_write_desc_tag(axis_dma_write_desc_tag), + .s_axis_write_desc_valid(axis_dma_write_desc_valid), + .s_axis_write_desc_ready(axis_dma_write_desc_ready), + + /* + * AXI write descriptor status output + */ + .m_axis_write_desc_status_tag(axis_dma_write_desc_status_tag), + .m_axis_write_desc_status_error(axis_dma_write_desc_status_error), + .m_axis_write_desc_status_valid(axis_dma_write_desc_status_valid), + + /* + * RAM interface + */ + .ram_rd_cmd_sel(ram_rd_cmd_sel), + .ram_rd_cmd_addr(ram_rd_cmd_addr), + .ram_rd_cmd_valid(ram_rd_cmd_valid), + .ram_rd_cmd_ready(ram_rd_cmd_ready), + .ram_rd_resp_data(ram_rd_resp_data), + .ram_rd_resp_valid(ram_rd_resp_valid), + .ram_rd_resp_ready(ram_rd_resp_ready), + .ram_wr_cmd_sel(ram_wr_cmd_sel), + .ram_wr_cmd_be(ram_wr_cmd_be), + .ram_wr_cmd_addr(ram_wr_cmd_addr), + .ram_wr_cmd_data(ram_wr_cmd_data), + .ram_wr_cmd_valid(ram_wr_cmd_valid), + .ram_wr_cmd_ready(ram_wr_cmd_ready), + .ram_wr_done(ram_wr_done), + + /* + * Configuration + */ + .read_enable(1'b1), + .write_enable(1'b1), + .ext_tag_enable(ext_tag_enable), + .requester_id({bus_num, 5'd0, 3'd0}), + .max_read_request_size(max_read_request_size), + .max_payload_size(max_payload_size), + + /* + * Status + */ + .status_error_cor(status_error_cor_int[2]), + .status_error_uncor(status_error_uncor_int[2]) +); + +pulse_merge #( + .INPUT_WIDTH(3), + .COUNT_WIDTH(4) +) +status_error_cor_pm_inst ( + .clk(clk), + .rst(rst), + + .pulse_in(status_error_cor_int), + .count_out(), + .pulse_out(status_error_cor) +); + +pulse_merge #( + .INPUT_WIDTH(3), + .COUNT_WIDTH(4) +) +status_error_uncor_pm_inst ( + .clk(clk), + .rst(rst), + + .pulse_in(status_error_uncor_int), + .count_out(), + .pulse_out(status_error_uncor) +); + +example_core #( + .AXIL_DATA_WIDTH(AXIL_DATA_WIDTH), + .AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH), + .AXIL_STRB_WIDTH(AXIL_STRB_WIDTH), + .DMA_ADDR_WIDTH(PCIE_ADDR_WIDTH), + .DMA_LEN_WIDTH(DMA_LEN_WIDTH), + .DMA_TAG_WIDTH(DMA_TAG_WIDTH), + .RAM_SEG_COUNT(RAM_SEG_COUNT), + .RAM_SEG_DATA_WIDTH(RAM_SEG_DATA_WIDTH), + .RAM_SEG_ADDR_WIDTH(RAM_SEG_ADDR_WIDTH), + .RAM_SEG_BE_WIDTH(RAM_SEG_BE_WIDTH), + .RAM_SEL_WIDTH(RAM_SEL_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH) +) +core_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI Lite control interface + */ + .s_axil_ctrl_awaddr(axil_ctrl_awaddr), + .s_axil_ctrl_awprot(axil_ctrl_awprot), + .s_axil_ctrl_awvalid(axil_ctrl_awvalid), + .s_axil_ctrl_awready(axil_ctrl_awready), + .s_axil_ctrl_wdata(axil_ctrl_wdata), + .s_axil_ctrl_wstrb(axil_ctrl_wstrb), + .s_axil_ctrl_wvalid(axil_ctrl_wvalid), + .s_axil_ctrl_wready(axil_ctrl_wready), + .s_axil_ctrl_bresp(axil_ctrl_bresp), + .s_axil_ctrl_bvalid(axil_ctrl_bvalid), + .s_axil_ctrl_bready(axil_ctrl_bready), + .s_axil_ctrl_araddr(axil_ctrl_araddr), + .s_axil_ctrl_arprot(axil_ctrl_arprot), + .s_axil_ctrl_arvalid(axil_ctrl_arvalid), + .s_axil_ctrl_arready(axil_ctrl_arready), + .s_axil_ctrl_rdata(axil_ctrl_rdata), + .s_axil_ctrl_rresp(axil_ctrl_rresp), + .s_axil_ctrl_rvalid(axil_ctrl_rvalid), + .s_axil_ctrl_rready(axil_ctrl_rready), + + /* + * AXI read descriptor output + */ + .m_axis_dma_read_desc_dma_addr(axis_dma_read_desc_dma_addr), + .m_axis_dma_read_desc_ram_sel(axis_dma_read_desc_ram_sel), + .m_axis_dma_read_desc_ram_addr(axis_dma_read_desc_ram_addr), + .m_axis_dma_read_desc_len(axis_dma_read_desc_len), + .m_axis_dma_read_desc_tag(axis_dma_read_desc_tag), + .m_axis_dma_read_desc_valid(axis_dma_read_desc_valid), + .m_axis_dma_read_desc_ready(axis_dma_read_desc_ready), + + /* + * AXI read descriptor status input + */ + .s_axis_dma_read_desc_status_tag(axis_dma_read_desc_status_tag), + .s_axis_dma_read_desc_status_error(axis_dma_read_desc_status_error), + .s_axis_dma_read_desc_status_valid(axis_dma_read_desc_status_valid), + + /* + * AXI write descriptor output + */ + .m_axis_dma_write_desc_dma_addr(axis_dma_write_desc_dma_addr), + .m_axis_dma_write_desc_ram_sel(axis_dma_write_desc_ram_sel), + .m_axis_dma_write_desc_ram_addr(axis_dma_write_desc_ram_addr), + .m_axis_dma_write_desc_len(axis_dma_write_desc_len), + .m_axis_dma_write_desc_tag(axis_dma_write_desc_tag), + .m_axis_dma_write_desc_valid(axis_dma_write_desc_valid), + .m_axis_dma_write_desc_ready(axis_dma_write_desc_ready), + + /* + * AXI write descriptor status input + */ + .s_axis_dma_write_desc_status_tag(axis_dma_write_desc_status_tag), + .s_axis_dma_write_desc_status_error(axis_dma_write_desc_status_error), + .s_axis_dma_write_desc_status_valid(axis_dma_write_desc_status_valid), + + /* + * RAM interface + */ + .ram_rd_cmd_sel(ram_rd_cmd_sel), + .ram_rd_cmd_addr(ram_rd_cmd_addr), + .ram_rd_cmd_valid(ram_rd_cmd_valid), + .ram_rd_cmd_ready(ram_rd_cmd_ready), + .ram_rd_resp_data(ram_rd_resp_data), + .ram_rd_resp_valid(ram_rd_resp_valid), + .ram_rd_resp_ready(ram_rd_resp_ready), + .ram_wr_cmd_sel(ram_wr_cmd_sel), + .ram_wr_cmd_be(ram_wr_cmd_be), + .ram_wr_cmd_addr(ram_wr_cmd_addr), + .ram_wr_cmd_data(ram_wr_cmd_data), + .ram_wr_cmd_valid(ram_wr_cmd_valid), + .ram_wr_cmd_ready(ram_wr_cmd_ready), + .ram_wr_done(ram_wr_done), + + /* + * MSI request outputs + */ + .msi_irq(msi_irq) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/common/rtl/example_core_pcie_s10.v b/fpga/lib/pcie/example/common/rtl/example_core_pcie_s10.v new file mode 100644 index 000000000..bae5a6e0d --- /dev/null +++ b/fpga/lib/pcie/example/common/rtl/example_core_pcie_s10.v @@ -0,0 +1,478 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Example design core logic - Intel Stratix 10 H-Tile/L-Tile wrapper + */ +module example_core_pcie_s10 # +( + // H-Tile/L-Tile AVST segment count + parameter SEG_COUNT = 1, + // H-Tile/L-Tile AVST segment data width + parameter SEG_DATA_WIDTH = 256, + // H-Tile/L-Tile AVST segment empty signal width + parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32), + // TX sequence number width + parameter TX_SEQ_NUM_WIDTH = 6, + // TX sequence number tracking enable + parameter TX_SEQ_NUM_ENABLE = 1, + // Tile selection (0 for H-Tile, 1 for L-Tile) + parameter L_TILE = 0, + // PCIe tag count + parameter PCIE_TAG_COUNT = 256, + // Operation table size (read) + parameter READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + // In-flight transmit limit (read) + parameter READ_TX_LIMIT = 2**TX_SEQ_NUM_WIDTH, + // Transmit flow control (read) + parameter READ_TX_FC_ENABLE = 1, + // Operation table size (write) + parameter WRITE_OP_TABLE_SIZE = 2**TX_SEQ_NUM_WIDTH, + // In-flight transmit limit (write) + parameter WRITE_TX_LIMIT = 2**TX_SEQ_NUM_WIDTH, + // Transmit flow control (write) + parameter WRITE_TX_FC_ENABLE = 1, + // BAR0 aperture (log2 size) + parameter BAR0_APERTURE = 24, + // BAR2 aperture (log2 size) + parameter BAR2_APERTURE = 24 +) +( + input wire clk, + input wire rst, + + /* + * H-Tile/L-Tile RX AVST interface + */ + input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data, + input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty, + input wire [SEG_COUNT-1:0] rx_st_sop, + input wire [SEG_COUNT-1:0] rx_st_eop, + input wire [SEG_COUNT-1:0] rx_st_valid, + output wire rx_st_ready, + input wire [SEG_COUNT-1:0] rx_st_vf_active, + input wire [SEG_COUNT*2-1:0] rx_st_func_num, + input wire [SEG_COUNT*11-1:0] rx_st_vf_num, + input wire [SEG_COUNT*3-1:0] rx_st_bar_range, + + /* + * H-Tile/L-Tile TX AVST interface + */ + output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data, + output wire [SEG_COUNT-1:0] tx_st_sop, + output wire [SEG_COUNT-1:0] tx_st_eop, + output wire [SEG_COUNT-1:0] tx_st_valid, + input wire tx_st_ready, + output wire [SEG_COUNT-1:0] tx_st_err, + + /* + * H-Tile/L-Tile TX flow control + */ + input wire [7:0] tx_ph_cdts, + input wire [11:0] tx_pd_cdts, + input wire [7:0] tx_nph_cdts, + input wire [11:0] tx_npd_cdts, + input wire [7:0] tx_cplh_cdts, + input wire [11:0] tx_cpld_cdts, + input wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed, + input wire [SEG_COUNT-1:0] tx_data_cdts_consumed, + input wire [SEG_COUNT*2-1:0] tx_cdts_type, + input wire [SEG_COUNT*1-1:0] tx_cdts_data_value, + + /* + * H-Tile/L-Tile MSI interrupt interface + */ + output wire app_msi_req, + input wire app_msi_ack, + output wire [2:0] app_msi_tc, + output wire [4:0] app_msi_num, + output wire [1:0] app_msi_func_num, + + /* + * H-Tile/L-Tile configuration interface + */ + input wire [31:0] tl_cfg_ctl, + input wire [4:0] tl_cfg_add, + input wire [1:0] tl_cfg_func +); + +parameter TLP_SEG_COUNT = 1; +parameter TLP_SEG_DATA_WIDTH = (SEG_COUNT*SEG_DATA_WIDTH)/TLP_SEG_COUNT; +parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32; +parameter TLP_SEG_HDR_WIDTH = 128; +parameter TX_SEQ_NUM_COUNT = SEG_COUNT; +parameter PF_COUNT = 1; +parameter VF_COUNT = 0; +parameter F_COUNT = PF_COUNT+VF_COUNT; +parameter MSI_COUNT = 32; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_rx_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_rx_req_tlp_hdr; +wire [TLP_SEG_COUNT*3-1:0] pcie_rx_req_tlp_bar_id; +wire [TLP_SEG_COUNT*8-1:0] pcie_rx_req_tlp_func_num; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_eop; +wire pcie_rx_req_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_rx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_rx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT*4-1:0] pcie_rx_cpl_tlp_error; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_eop; +wire pcie_rx_cpl_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_rd_req_tlp_hdr; +wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] pcie_tx_rd_req_tlp_seq; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_eop; +wire pcie_tx_rd_req_tlp_ready; + +wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] axis_pcie_rd_req_tx_seq_num; +wire [TX_SEQ_NUM_COUNT-1:0] axis_pcie_rd_req_tx_seq_num_valid; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_tx_wr_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] pcie_tx_wr_req_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_wr_req_tlp_hdr; +wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] pcie_tx_wr_req_tlp_seq; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_eop; +wire pcie_tx_wr_req_tlp_ready; + +wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] axis_pcie_wr_req_tx_seq_num; +wire [TX_SEQ_NUM_COUNT-1:0] axis_pcie_wr_req_tx_seq_num_valid; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_tx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] pcie_tx_cpl_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_eop; +wire pcie_tx_cpl_tlp_ready; + +wire [7:0] pcie_tx_fc_ph_av; +wire [11:0] pcie_tx_fc_pd_av; +wire [7:0] pcie_tx_fc_nph_av; + +wire ext_tag_enable; +wire [7:0] bus_num; +wire [2:0] max_read_request_size; +wire [2:0] max_payload_size; + +wire [MSI_COUNT-1:0] msi_irq; + +pcie_s10_if #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .L_TILE(L_TILE), + .PF_COUNT(1), + .VF_COUNT(0), + .F_COUNT(PF_COUNT+VF_COUNT), + .IO_BAR_INDEX(5), + .MSI_ENABLE(1), + .MSI_COUNT(MSI_COUNT) +) +pcie_us_if_inst ( + .clk(clk), + .rst(rst), + + /* + * H-Tile/L-Tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + /* + * H-Tile/L-Tile TX AVST interface + */ + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + /* + * H-Tile/L-Tile TX flow control + */ + .tx_ph_cdts(tx_ph_cdts), + .tx_pd_cdts(tx_pd_cdts), + .tx_nph_cdts(tx_nph_cdts), + .tx_npd_cdts(tx_npd_cdts), + .tx_cplh_cdts(tx_cplh_cdts), + .tx_cpld_cdts(tx_cpld_cdts), + .tx_hdr_cdts_consumed(tx_hdr_cdts_consumed), + .tx_data_cdts_consumed(tx_data_cdts_consumed), + .tx_cdts_type(tx_cdts_type), + .tx_cdts_data_value(tx_cdts_data_value), + + /* + * H-Tile/L-Tile MSI interrupt interface + */ + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + /* + * H-Tile/L-Tile configuration interface + */ + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func), + + /* + * TLP output (request to BAR) + */ + .rx_req_tlp_data(pcie_rx_req_tlp_data), + .rx_req_tlp_hdr(pcie_rx_req_tlp_hdr), + .rx_req_tlp_bar_id(pcie_rx_req_tlp_bar_id), + .rx_req_tlp_func_num(pcie_rx_req_tlp_func_num), + .rx_req_tlp_valid(pcie_rx_req_tlp_valid), + .rx_req_tlp_sop(pcie_rx_req_tlp_sop), + .rx_req_tlp_eop(pcie_rx_req_tlp_eop), + .rx_req_tlp_ready(pcie_rx_req_tlp_ready), + + /* + * TLP output (completion to DMA) + */ + .rx_cpl_tlp_data(pcie_rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(pcie_rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(pcie_rx_cpl_tlp_error), + .rx_cpl_tlp_valid(pcie_rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(pcie_rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(pcie_rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(pcie_rx_cpl_tlp_ready), + + /* + * TLP input (read request from DMA) + */ + .tx_rd_req_tlp_hdr(pcie_tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(pcie_tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(pcie_tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(pcie_tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(pcie_tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(pcie_tx_rd_req_tlp_ready), + + /* + * Transmit sequence number output (DMA read request) + */ + .m_axis_rd_req_tx_seq_num(axis_pcie_rd_req_tx_seq_num), + .m_axis_rd_req_tx_seq_num_valid(axis_pcie_rd_req_tx_seq_num_valid), + + /* + * TLP input (write request from DMA) + */ + .tx_wr_req_tlp_data(pcie_tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(pcie_tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(pcie_tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(pcie_tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(pcie_tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(pcie_tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(pcie_tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(pcie_tx_wr_req_tlp_ready), + + /* + * Transmit sequence number output (DMA write request) + */ + .m_axis_wr_req_tx_seq_num(axis_pcie_wr_req_tx_seq_num), + .m_axis_wr_req_tx_seq_num_valid(axis_pcie_wr_req_tx_seq_num_valid), + + /* + * TLP input (completion from BAR) + */ + .tx_cpl_tlp_data(pcie_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(pcie_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(pcie_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(pcie_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(pcie_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(pcie_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(pcie_tx_cpl_tlp_ready), + + /* + * Flow control + */ + .tx_fc_ph_av(pcie_tx_fc_ph_av), + .tx_fc_pd_av(pcie_tx_fc_pd_av), + .tx_fc_nph_av(pcie_tx_fc_nph_av), + .tx_fc_npd_av(), + .tx_fc_cplh_av(), + .tx_fc_cpld_av(), + + /* + * Configuration outputs + */ + .ext_tag_enable(ext_tag_enable), + .bus_num(bus_num), + .max_read_request_size(max_read_request_size), + .max_payload_size(max_payload_size), + + /* + * MSI request inputs + */ + .msi_irq(msi_irq) +); + +example_core_pcie #( + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .TX_SEQ_NUM_ENABLE(TX_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE), + .READ_TX_LIMIT(READ_TX_LIMIT), + .READ_TX_FC_ENABLE(READ_TX_FC_ENABLE), + .WRITE_OP_TABLE_SIZE(WRITE_OP_TABLE_SIZE), + .WRITE_TX_LIMIT(WRITE_TX_LIMIT), + .WRITE_TX_FC_ENABLE(WRITE_TX_FC_ENABLE), + .TLP_FORCE_64_BIT_ADDR(0), + .CHECK_BUS_NUMBER(1), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +core_pcie_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input (request) + */ + .rx_req_tlp_data(pcie_rx_req_tlp_data), + .rx_req_tlp_hdr(pcie_rx_req_tlp_hdr), + .rx_req_tlp_valid(pcie_rx_req_tlp_valid), + .rx_req_tlp_bar_id(pcie_rx_req_tlp_bar_id), + .rx_req_tlp_func_num(pcie_rx_req_tlp_func_num), + .rx_req_tlp_sop(pcie_rx_req_tlp_sop), + .rx_req_tlp_eop(pcie_rx_req_tlp_eop), + .rx_req_tlp_ready(pcie_rx_req_tlp_ready), + + /* + * TLP output (completion) + */ + .tx_cpl_tlp_data(pcie_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(pcie_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(pcie_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(pcie_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(pcie_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(pcie_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(pcie_tx_cpl_tlp_ready), + + /* + * TLP input (completion) + */ + .rx_cpl_tlp_data(pcie_rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(pcie_rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(pcie_rx_cpl_tlp_error), + .rx_cpl_tlp_valid(pcie_rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(pcie_rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(pcie_rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(pcie_rx_cpl_tlp_ready), + + /* + * TLP output (read request) + */ + .tx_rd_req_tlp_hdr(pcie_tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(pcie_tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(pcie_tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(pcie_tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(pcie_tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(pcie_tx_rd_req_tlp_ready), + + /* + * TLP output (write request) + */ + .tx_wr_req_tlp_data(pcie_tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(pcie_tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(pcie_tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(pcie_tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(pcie_tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(pcie_tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(pcie_tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(pcie_tx_wr_req_tlp_ready), + + /* + * Transmit sequence number input + */ + .s_axis_rd_req_tx_seq_num(axis_pcie_rd_req_tx_seq_num), + .s_axis_rd_req_tx_seq_num_valid(axis_pcie_rd_req_tx_seq_num_valid), + .s_axis_wr_req_tx_seq_num(axis_pcie_wr_req_tx_seq_num), + .s_axis_wr_req_tx_seq_num_valid(axis_pcie_wr_req_tx_seq_num_valid), + + /* + * Transmit flow control + */ + .pcie_tx_fc_ph_av(pcie_tx_fc_ph_av), + .pcie_tx_fc_pd_av(pcie_tx_fc_pd_av), + .pcie_tx_fc_nph_av(pcie_tx_fc_nph_av), + + /* + * Configuration + */ + .bus_num(bus_num), + .ext_tag_enable(ext_tag_enable), + .max_read_request_size(max_read_request_size), + .max_payload_size(max_payload_size), + + /* + * Status + */ + .status_error_cor(), + .status_error_uncor(), + + /* + * MSI request outputs + */ + .msi_irq(msi_irq) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/common/rtl/example_core_pcie_us.v b/fpga/lib/pcie/example/common/rtl/example_core_pcie_us.v new file mode 100644 index 000000000..f439c8f52 --- /dev/null +++ b/fpga/lib/pcie/example/common/rtl/example_core_pcie_us.v @@ -0,0 +1,573 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Example design core logic - Xilinx UltraScale wrapper + */ +module example_core_pcie_us # +( + // Width of PCIe AXI stream interfaces in bits + parameter AXIS_PCIE_DATA_WIDTH = 256, + // PCIe AXI stream tkeep signal width (words per cycle) + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + // PCIe AXI stream RC tuser signal width + parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161, + // PCIe AXI stream RQ tuser signal width + parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 60 : 137, + // PCIe AXI stream CQ tuser signal width + parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183, + // PCIe AXI stream CC tuser signal width + parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81, + // RQ sequence number width + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + // RQ sequence number tracking enable + parameter RQ_SEQ_NUM_ENABLE = 1, + // PCIe tag count + parameter PCIE_TAG_COUNT = 256, + // Operation table size (read) + parameter READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + // In-flight transmit limit (read) + parameter READ_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH-1), + // Transmit flow control (read) + parameter READ_TX_FC_ENABLE = 1, + // Operation table size (write) + parameter WRITE_OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH-1), + // In-flight transmit limit (write) + parameter WRITE_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH-1), + // Transmit flow control (write) + parameter WRITE_TX_FC_ENABLE = 1, + // BAR0 aperture (log2 size) + parameter BAR0_APERTURE = 24, + // BAR2 aperture (log2 size) + parameter BAR2_APERTURE = 24 +) +( + input wire clk, + input wire rst, + + /* + * AXI input (RC) + */ + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep, + input wire s_axis_rc_tvalid, + output wire s_axis_rc_tready, + input wire s_axis_rc_tlast, + input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser, + + /* + * AXI output (RQ) + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep, + output wire m_axis_rq_tvalid, + input wire m_axis_rq_tready, + output wire m_axis_rq_tlast, + output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser, + + /* + * AXI input (CQ) + */ + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep, + input wire s_axis_cq_tvalid, + output wire s_axis_cq_tready, + input wire s_axis_cq_tlast, + input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser, + + /* + * AXI output (CC) + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep, + output wire m_axis_cc_tvalid, + input wire m_axis_cc_tready, + output wire m_axis_cc_tlast, + output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser, + + /* + * Transmit sequence number input + */ + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0, + input wire s_axis_rq_seq_num_valid_0, + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1, + input wire s_axis_rq_seq_num_valid_1, + + /* + * Flow control + */ + input wire [7:0] cfg_fc_ph, + input wire [11:0] cfg_fc_pd, + input wire [7:0] cfg_fc_nph, + input wire [11:0] cfg_fc_npd, + input wire [7:0] cfg_fc_cplh, + input wire [11:0] cfg_fc_cpld, + output wire [2:0] cfg_fc_sel, + + /* + * Configuration interface + */ + output wire [9:0] cfg_mgmt_addr, + output wire [7:0] cfg_mgmt_function_number, + output wire cfg_mgmt_write, + output wire [31:0] cfg_mgmt_write_data, + output wire [3:0] cfg_mgmt_byte_enable, + output wire cfg_mgmt_read, + input wire [31:0] cfg_mgmt_read_data, + input wire cfg_mgmt_read_write_done, + + /* + * Interrupt interface + */ + input wire [3:0] cfg_interrupt_msi_enable, + input wire [7:0] cfg_interrupt_msi_vf_enable, + input wire [11:0] cfg_interrupt_msi_mmenable, + input wire cfg_interrupt_msi_mask_update, + input wire [31:0] cfg_interrupt_msi_data, + output wire [3:0] cfg_interrupt_msi_select, + output wire [31:0] cfg_interrupt_msi_int, + output wire [31:0] cfg_interrupt_msi_pending_status, + output wire cfg_interrupt_msi_pending_status_data_enable, + output wire [3:0] cfg_interrupt_msi_pending_status_function_num, + input wire cfg_interrupt_msi_sent, + input wire cfg_interrupt_msi_fail, + output wire [2:0] cfg_interrupt_msi_attr, + output wire cfg_interrupt_msi_tph_present, + output wire [1:0] cfg_interrupt_msi_tph_type, + output wire [8:0] cfg_interrupt_msi_tph_st_tag, + output wire [3:0] cfg_interrupt_msi_function_number, + + /* + * Configuration + */ + input wire [2:0] cfg_max_read_req, + input wire [2:0] cfg_max_payload, + + /* + * Status + */ + output wire status_error_cor, + output wire status_error_uncor +); + +parameter TLP_SEG_COUNT = 1; +parameter TLP_SEG_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH/TLP_SEG_COUNT; +parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32; +parameter TLP_SEG_HDR_WIDTH = 128; +parameter TX_SEQ_NUM_COUNT = AXIS_PCIE_DATA_WIDTH < 512 ? 1 : 2; +parameter TX_SEQ_NUM_WIDTH = RQ_SEQ_NUM_WIDTH-1; +parameter TX_SEQ_NUM_ENABLE = RQ_SEQ_NUM_ENABLE; +parameter PF_COUNT = 1; +parameter VF_COUNT = 0; +parameter F_COUNT = PF_COUNT+VF_COUNT; +parameter MSI_COUNT = 32; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_rx_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_rx_req_tlp_hdr; +wire [TLP_SEG_COUNT*3-1:0] pcie_rx_req_tlp_bar_id; +wire [TLP_SEG_COUNT*8-1:0] pcie_rx_req_tlp_func_num; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_rx_req_tlp_eop; +wire pcie_rx_req_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_rx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_rx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT*4-1:0] pcie_rx_cpl_tlp_error; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_rx_cpl_tlp_eop; +wire pcie_rx_cpl_tlp_ready; + +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_rd_req_tlp_hdr; +wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] pcie_tx_rd_req_tlp_seq; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_rd_req_tlp_eop; +wire pcie_tx_rd_req_tlp_ready; + +wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] axis_pcie_rd_req_tx_seq_num; +wire [TX_SEQ_NUM_COUNT-1:0] axis_pcie_rd_req_tx_seq_num_valid; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_tx_wr_req_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] pcie_tx_wr_req_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_wr_req_tlp_hdr; +wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] pcie_tx_wr_req_tlp_seq; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_wr_req_tlp_eop; +wire pcie_tx_wr_req_tlp_ready; + +wire [TX_SEQ_NUM_COUNT*TX_SEQ_NUM_WIDTH-1:0] axis_pcie_wr_req_tx_seq_num; +wire [TX_SEQ_NUM_COUNT-1:0] axis_pcie_wr_req_tx_seq_num_valid; + +wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] pcie_tx_cpl_tlp_data; +wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] pcie_tx_cpl_tlp_strb; +wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] pcie_tx_cpl_tlp_hdr; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_valid; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_sop; +wire [TLP_SEG_COUNT-1:0] pcie_tx_cpl_tlp_eop; +wire pcie_tx_cpl_tlp_ready; + +wire [7:0] pcie_tx_fc_ph_av; +wire [11:0] pcie_tx_fc_pd_av; +wire [7:0] pcie_tx_fc_nph_av; + +wire ext_tag_enable; +wire [MSI_COUNT-1:0] msi_irq; + +pcie_us_if #( + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .PF_COUNT(1), + .VF_COUNT(0), + .F_COUNT(PF_COUNT+VF_COUNT), + .READ_EXT_TAG_ENABLE(1), + .READ_MAX_READ_REQ_SIZE(1), + .READ_MAX_PAYLOAD_SIZE(1), + .MSI_ENABLE(1), + .MSI_COUNT(MSI_COUNT) +) +pcie_us_if_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI input (RC) + */ + .s_axis_rc_tdata(s_axis_rc_tdata), + .s_axis_rc_tkeep(s_axis_rc_tkeep), + .s_axis_rc_tvalid(s_axis_rc_tvalid), + .s_axis_rc_tready(s_axis_rc_tready), + .s_axis_rc_tlast(s_axis_rc_tlast), + .s_axis_rc_tuser(s_axis_rc_tuser), + + /* + * AXI output (RQ) + */ + .m_axis_rq_tdata(m_axis_rq_tdata), + .m_axis_rq_tkeep(m_axis_rq_tkeep), + .m_axis_rq_tvalid(m_axis_rq_tvalid), + .m_axis_rq_tready(m_axis_rq_tready), + .m_axis_rq_tlast(m_axis_rq_tlast), + .m_axis_rq_tuser(m_axis_rq_tuser), + + /* + * AXI input (CQ) + */ + .s_axis_cq_tdata(s_axis_cq_tdata), + .s_axis_cq_tkeep(s_axis_cq_tkeep), + .s_axis_cq_tvalid(s_axis_cq_tvalid), + .s_axis_cq_tready(s_axis_cq_tready), + .s_axis_cq_tlast(s_axis_cq_tlast), + .s_axis_cq_tuser(s_axis_cq_tuser), + + /* + * AXI output (CC) + */ + .m_axis_cc_tdata(m_axis_cc_tdata), + .m_axis_cc_tkeep(m_axis_cc_tkeep), + .m_axis_cc_tvalid(m_axis_cc_tvalid), + .m_axis_cc_tready(m_axis_cc_tready), + .m_axis_cc_tlast(m_axis_cc_tlast), + .m_axis_cc_tuser(m_axis_cc_tuser), + + /* + * Transmit sequence number input + */ + .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), + .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), + .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), + .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), + + /* + * Flow control + */ + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + /* + * Configuration interface + */ + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + /* + * Interrupt interface + */ + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * TLP output (request to BAR) + */ + .rx_req_tlp_data(pcie_rx_req_tlp_data), + .rx_req_tlp_hdr(pcie_rx_req_tlp_hdr), + .rx_req_tlp_bar_id(pcie_rx_req_tlp_bar_id), + .rx_req_tlp_func_num(pcie_rx_req_tlp_func_num), + .rx_req_tlp_valid(pcie_rx_req_tlp_valid), + .rx_req_tlp_sop(pcie_rx_req_tlp_sop), + .rx_req_tlp_eop(pcie_rx_req_tlp_eop), + .rx_req_tlp_ready(pcie_rx_req_tlp_ready), + + /* + * TLP output (completion to DMA) + */ + .rx_cpl_tlp_data(pcie_rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(pcie_rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(pcie_rx_cpl_tlp_error), + .rx_cpl_tlp_valid(pcie_rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(pcie_rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(pcie_rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(pcie_rx_cpl_tlp_ready), + + /* + * TLP input (read request from DMA) + */ + .tx_rd_req_tlp_hdr(pcie_tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(pcie_tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(pcie_tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(pcie_tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(pcie_tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(pcie_tx_rd_req_tlp_ready), + + /* + * Transmit sequence number output (DMA read request) + */ + .m_axis_rd_req_tx_seq_num(axis_pcie_rd_req_tx_seq_num), + .m_axis_rd_req_tx_seq_num_valid(axis_pcie_rd_req_tx_seq_num_valid), + + /* + * TLP input (write request from DMA) + */ + .tx_wr_req_tlp_data(pcie_tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(pcie_tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(pcie_tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(pcie_tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(pcie_tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(pcie_tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(pcie_tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(pcie_tx_wr_req_tlp_ready), + + /* + * Transmit sequence number output (DMA write request) + */ + .m_axis_wr_req_tx_seq_num(axis_pcie_wr_req_tx_seq_num), + .m_axis_wr_req_tx_seq_num_valid(axis_pcie_wr_req_tx_seq_num_valid), + + /* + * TLP input (completion from BAR) + */ + .tx_cpl_tlp_data(pcie_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(pcie_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(pcie_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(pcie_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(pcie_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(pcie_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(pcie_tx_cpl_tlp_ready), + + /* + * Flow control + */ + .tx_fc_ph_av(pcie_tx_fc_ph_av), + .tx_fc_pd_av(pcie_tx_fc_pd_av), + .tx_fc_nph_av(pcie_tx_fc_nph_av), + .tx_fc_npd_av(), + .tx_fc_cplh_av(), + .tx_fc_cpld_av(), + + /* + * Configuration outputs + */ + .ext_tag_enable(ext_tag_enable), + .max_read_request_size(), + .max_payload_size(), + + /* + * MSI request inputs + */ + .msi_irq(msi_irq) +); + +example_core_pcie #( + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_COUNT(TX_SEQ_NUM_COUNT), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH), + .TX_SEQ_NUM_ENABLE(TX_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(READ_OP_TABLE_SIZE), + .READ_TX_LIMIT(READ_TX_LIMIT), + .READ_TX_FC_ENABLE(READ_TX_FC_ENABLE), + .WRITE_OP_TABLE_SIZE(WRITE_OP_TABLE_SIZE), + .WRITE_TX_LIMIT(WRITE_TX_LIMIT), + .WRITE_TX_FC_ENABLE(WRITE_TX_FC_ENABLE), + .TLP_FORCE_64_BIT_ADDR(1), + .CHECK_BUS_NUMBER(0), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +core_pcie_inst ( + .clk(clk), + .rst(rst), + + /* + * TLP input (request) + */ + .rx_req_tlp_data(pcie_rx_req_tlp_data), + .rx_req_tlp_hdr(pcie_rx_req_tlp_hdr), + .rx_req_tlp_valid(pcie_rx_req_tlp_valid), + .rx_req_tlp_bar_id(pcie_rx_req_tlp_bar_id), + .rx_req_tlp_func_num(pcie_rx_req_tlp_func_num), + .rx_req_tlp_sop(pcie_rx_req_tlp_sop), + .rx_req_tlp_eop(pcie_rx_req_tlp_eop), + .rx_req_tlp_ready(pcie_rx_req_tlp_ready), + + /* + * TLP output (completion) + */ + .tx_cpl_tlp_data(pcie_tx_cpl_tlp_data), + .tx_cpl_tlp_strb(pcie_tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(pcie_tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(pcie_tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(pcie_tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(pcie_tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(pcie_tx_cpl_tlp_ready), + + /* + * TLP input (completion) + */ + .rx_cpl_tlp_data(pcie_rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(pcie_rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(pcie_rx_cpl_tlp_error), + .rx_cpl_tlp_valid(pcie_rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(pcie_rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(pcie_rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(pcie_rx_cpl_tlp_ready), + + /* + * TLP output (read request) + */ + .tx_rd_req_tlp_hdr(pcie_tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(pcie_tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(pcie_tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(pcie_tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(pcie_tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(pcie_tx_rd_req_tlp_ready), + + /* + * TLP output (write request) + */ + .tx_wr_req_tlp_data(pcie_tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(pcie_tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(pcie_tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(pcie_tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(pcie_tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(pcie_tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(pcie_tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(pcie_tx_wr_req_tlp_ready), + + /* + * Transmit sequence number input + */ + .s_axis_rd_req_tx_seq_num(axis_pcie_rd_req_tx_seq_num), + .s_axis_rd_req_tx_seq_num_valid(axis_pcie_rd_req_tx_seq_num_valid), + .s_axis_wr_req_tx_seq_num(axis_pcie_wr_req_tx_seq_num), + .s_axis_wr_req_tx_seq_num_valid(axis_pcie_wr_req_tx_seq_num_valid), + + /* + * Transmit flow control + */ + .pcie_tx_fc_ph_av(pcie_tx_fc_ph_av), + .pcie_tx_fc_pd_av(pcie_tx_fc_pd_av), + .pcie_tx_fc_nph_av(pcie_tx_fc_nph_av), + + /* + * Configuration + */ + .bus_num(8'd0), + .ext_tag_enable(ext_tag_enable), + .max_read_request_size(cfg_max_read_req), + .max_payload_size(cfg_max_payload), + + /* + * Status + */ + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor), + + /* + * MSI request outputs + */ + .msi_irq(msi_irq) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie/Makefile b/fpga/lib/pcie/example/common/tb/example_core_pcie/Makefile new file mode 100644 index 000000000..080dab6b3 --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie/Makefile @@ -0,0 +1,135 @@ +# Copyright (c) 2021 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 = example_core_pcie +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/example_core.v +VERILOG_SOURCES += ../../rtl/axi_ram.v +VERILOG_SOURCES += ../../../../rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../../../rtl/dma_psdpram.v +VERILOG_SOURCES += ../../../../rtl/arbiter.v +VERILOG_SOURCES += ../../../../rtl/priority_encoder.v +VERILOG_SOURCES += ../../../../rtl/pulse_merge.v + +# module parameters +export PARAM_TLP_SEG_COUNT ?= 1 +export PARAM_TLP_SEG_DATA_WIDTH ?= 512 +export PARAM_TLP_SEG_STRB_WIDTH ?= $(shell expr $(PARAM_TLP_SEG_DATA_WIDTH) / 32 ) +export PARAM_TLP_SEG_HDR_WIDTH ?= 128 +export PARAM_TX_SEQ_NUM_COUNT ?= 1 +export PARAM_TX_SEQ_NUM_WIDTH ?= 6 +export PARAM_TX_SEQ_NUM_ENABLE ?= 1 +export PARAM_PCIE_TAG_COUNT ?= 256 +export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT) +export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_READ_TX_FC_ENABLE ?= 1 +export PARAM_WRITE_OP_TABLE_SIZE ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_WRITE_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_WRITE_TX_FC_ENABLE ?= 1 +export PARAM_TLP_FORCE_64_BIT_ADDR ?= 0 +export PARAM_CHECK_BUS_NUMBER ?= 1 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_COUNT=$(PARAM_TLP_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_DATA_WIDTH=$(PARAM_TLP_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_STRB_WIDTH=$(PARAM_TLP_SEG_STRB_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_HDR_WIDTH=$(PARAM_TLP_SEG_HDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_COUNT=$(PARAM_TX_SEQ_NUM_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_FORCE_64_BIT_ADDR=$(PARAM_TLP_FORCE_64_BIT_ADDR) + COMPILE_ARGS += -P $(TOPLEVEL).CHECK_BUS_NUMBER=$(PARAM_CHECK_BUS_NUMBER) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GTLP_SEG_COUNT=$(PARAM_TLP_SEG_COUNT) + COMPILE_ARGS += -GTLP_SEG_DATA_WIDTH=$(PARAM_TLP_SEG_DATA_WIDTH) + COMPILE_ARGS += -GTLP_SEG_STRB_WIDTH=$(PARAM_TLP_SEG_STRB_WIDTH) + COMPILE_ARGS += -GTLP_SEG_HDR_WIDTH=$(PARAM_TLP_SEG_HDR_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_COUNT=$(PARAM_TX_SEQ_NUM_COUNT) + COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -GWRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -GWRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -GWRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -GTLP_FORCE_64_BIT_ADDR=$(PARAM_TLP_FORCE_64_BIT_ADDR) + COMPILE_ARGS += -GCHECK_BUS_NUMBER=$(PARAM_CHECK_BUS_NUMBER) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie/pcie_if.py b/fpga/lib/pcie/example/common/tb/example_core_pcie/pcie_if.py new file mode 120000 index 000000000..bbc6e19bb --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie/pcie_if.py @@ -0,0 +1 @@ +../../../../tb/pcie_if.py \ No newline at end of file diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie/test_example_core_pcie.py b/fpga/lib/pcie/example/common/tb/example_core_pcie/test_example_core_pcie.py new file mode 100644 index 000000000..d1d7c13de --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie/test_example_core_pcie.py @@ -0,0 +1,363 @@ +""" + +Copyright (c) 2021 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 +import sys + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.axi.utils import hexdump_str + +try: + from pcie_if import PcieIfDevice, PcieIfRxBus, PcieIfTxBus +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + from pcie_if import PcieIfDevice, PcieIfRxBus, PcieIfTxBus + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + # PCIe + self.rc = RootComplex() + + self.dev = PcieIfDevice( + clk=dut.clk, + rst=dut.rst, + + rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), + + tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp"), + + tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), + wr_req_tx_seq_num=dut.s_axis_wr_req_tx_seq_num, + wr_req_tx_seq_num_valid=dut.s_axis_wr_req_tx_seq_num_valid, + + tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), + rd_req_tx_seq_num=dut.s_axis_rd_req_tx_seq_num, + rd_req_tx_seq_num_valid=dut.s_axis_rd_req_tx_seq_num_valid, + + cfg_max_payload=dut.max_payload_size, + rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), + + cfg_max_read_req=dut.max_read_request_size, + cfg_ext_tag_enable=dut.ext_tag_enable, + + tx_fc_ph_av=dut.pcie_tx_fc_ph_av, + tx_fc_pd_av=dut.pcie_tx_fc_pd_av, + tx_fc_nph_av=dut.pcie_tx_fc_nph_av, + ) + + self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**24) + self.dev.functions[0].configure_bar(2, 2**24) + + dut.bus_num.setimmediatevalue(0) + + # monitor error outputs + self.status_error_cor_asserted = False + self.status_error_uncor_asserted = False + cocotb.fork(self._run_monitor_status_error_cor()) + cocotb.fork(self._run_monitor_status_error_uncor()) + + async def _run_monitor_status_error_cor(self): + while True: + await RisingEdge(self.dut.status_error_cor) + self.log.info("status_error_cor (correctable error) was asserted") + self.status_error_cor_asserted = True + + async def _run_monitor_status_error_uncor(self): + while True: + await RisingEdge(self.dut.status_error_uncor) + self.log.info("status_error_uncor (uncorrectable error) was asserted") + self.status_error_uncor_asserted = True + + async def cycle_reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.cycle_reset() + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.dut.bus_num <= tb.dev.bus_num + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # enable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0x3) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + tb.log.info("Test DMA block operations") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # disable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0) + + # configure operation (read) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001080, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001084, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001088, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00108c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001090, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001094, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001098, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00109c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001008, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00100c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001010, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001018, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00101c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001000, 1) + + await Timer(2000, 'ns') + + # configure operation (write) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001180, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001184, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001188, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00118c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001190, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001194, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001198, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00119c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001108, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00110c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001110, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001118, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00111c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001100, 1) + + await Timer(2000, 'ns') + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', '..', '..', 'rtl')) + + +@pytest.mark.parametrize("pcie_data_width", [64, 128, 256, 512]) +def test_example_core_pcie(request, pcie_data_width): + dut = "example_core_pcie" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "example_core.v"), + os.path.join(rtl_dir, "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + # segmented interface parameters + tlp_seg_count = 1 + tlp_seg_data_width = pcie_data_width // tlp_seg_count + tlp_seg_strb_width = tlp_seg_data_width // 32 + + parameters['TLP_SEG_COUNT'] = tlp_seg_count + parameters['TLP_SEG_DATA_WIDTH'] = tlp_seg_data_width + parameters['TLP_SEG_STRB_WIDTH'] = tlp_seg_strb_width + parameters['TLP_SEG_HDR_WIDTH'] = 128 + parameters['TX_SEQ_NUM_COUNT'] = 1 + parameters['TX_SEQ_NUM_WIDTH'] = 6 + parameters['TX_SEQ_NUM_ENABLE'] = 1 + parameters['PCIE_TAG_COUNT'] = 256 + parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT'] + parameters['READ_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['READ_TX_FC_ENABLE'] = 1 + parameters['WRITE_OP_TABLE_SIZE'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['WRITE_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['WRITE_TX_FC_ENABLE'] = 1 + parameters['TLP_FORCE_64_BIT_ADDR'] = 0 + parameters['CHECK_BUS_NUMBER'] = 1 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/Makefile b/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/Makefile new file mode 100644 index 000000000..b34339fd9 --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/Makefile @@ -0,0 +1,132 @@ +# Copyright (c) 2021 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 = example_core_pcie_s10 +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/example_core.v +VERILOG_SOURCES += ../../rtl/axi_ram.v +VERILOG_SOURCES += ../../../../rtl/pcie_s10_if.v +VERILOG_SOURCES += ../../../../rtl/pcie_s10_if_rx.v +VERILOG_SOURCES += ../../../../rtl/pcie_s10_if_tx.v +VERILOG_SOURCES += ../../../../rtl/pcie_s10_cfg.v +VERILOG_SOURCES += ../../../../rtl/pcie_s10_msi.v +VERILOG_SOURCES += ../../../../rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../../../rtl/dma_psdpram.v +VERILOG_SOURCES += ../../../../rtl/arbiter.v +VERILOG_SOURCES += ../../../../rtl/priority_encoder.v +VERILOG_SOURCES += ../../../../rtl/pulse_merge.v + +# module parameters +export PARAM_SEG_COUNT ?= 1 +export PARAM_SEG_DATA_WIDTH ?= 256 +export PARAM_SEG_EMPTY_WIDTH ?= $(shell python -c "print((($(PARAM_SEG_DATA_WIDTH)//32)-1).bit_length())" ) +export PARAM_TX_SEQ_NUM_WIDTH ?= 6 +export PARAM_TX_SEQ_NUM_ENABLE ?= 1 +export PARAM_L_TILE ?= 0 +export PARAM_PCIE_TAG_COUNT ?= 256 +export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT) +export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_READ_TX_FC_ENABLE ?= 1 +export PARAM_WRITE_OP_TABLE_SIZE ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_WRITE_TX_LIMIT ?= $(shell echo "$$(( 1 << $(PARAM_TX_SEQ_NUM_WIDTH) ))" ) +export PARAM_WRITE_TX_FC_ENABLE ?= 1 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).SEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).L_TILE=$(PARAM_L_TILE) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GSEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -GSEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -GSEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_ENABLE=$(PARAM_TX_SEQ_NUM_ENABLE) + COMPILE_ARGS += -GL_TILE=$(PARAM_L_TILE) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -GWRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -GWRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -GWRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/test_example_core_pcie_s10.py b/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/test_example_core_pcie_s10.py new file mode 100644 index 000000000..3c611035f --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie_s10/test_example_core_pcie_s10.py @@ -0,0 +1,400 @@ +""" + +Copyright (c) 2021 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 + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = S10PcieDevice( + # configuration options + pcie_generation=3, + # pcie_link_width=2, + # pld_clk_frequency=250e6, + l_tile=False, + + # signals + # Clock and reset + # npor=dut.npor, + # pin_perst=dut.pin_perst, + # ninit_done=dut.ninit_done, + # pld_clk_inuse=dut.pld_clk_inuse, + # pld_core_ready=dut.pld_core_ready, + reset_status=dut.rst, + # clr_st=dut.clr_st, + # refclk=dut.refclk, + coreclkout_hip=dut.clk, + + # RX interface + rx_bus=S10RxBus.from_prefix(dut, "rx_st"), + + # TX interface + tx_bus=S10TxBus.from_prefix(dut, "tx_st"), + + # TX flow control + tx_ph_cdts=dut.tx_ph_cdts, + tx_pd_cdts=dut.tx_pd_cdts, + tx_nph_cdts=dut.tx_nph_cdts, + tx_npd_cdts=dut.tx_npd_cdts, + tx_cplh_cdts=dut.tx_cplh_cdts, + tx_cpld_cdts=dut.tx_cpld_cdts, + tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, + tx_data_cdts_consumed=dut.tx_data_cdts_consumed, + tx_cdts_type=dut.tx_cdts_type, + tx_cdts_data_value=dut.tx_cdts_data_value, + + # Hard IP status + # int_status=dut.int_status, + # int_status_common=dut.int_status_common, + # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, + # derr_rpl=dut.derr_rpl, + # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, + # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, + # rx_par_err=dut.rx_par_err, + # tx_par_err=dut.tx_par_err, + # ltssmstate=dut.ltssmstate, + # link_up=dut.link_up, + # lane_act=dut.lane_act, + # currentspeed=dut.currentspeed, + + # Power management + # pm_linkst_in_l1=dut.pm_linkst_in_l1, + # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, + # pm_state=dut.pm_state, + # pm_dstate=dut.pm_dstate, + # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, + # apps_ready_entr_l23=dut.apps_ready_entr_l23, + # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, + # app_init_rst=dut.app_init_rst, + # app_xfer_pending=dut.app_xfer_pending, + + # Interrupt interface + app_msi_req=dut.app_msi_req, + app_msi_ack=dut.app_msi_ack, + app_msi_tc=dut.app_msi_tc, + app_msi_num=dut.app_msi_num, + app_msi_func_num=dut.app_msi_func_num, + # app_int_sts=dut.app_int_sts, + + # Error interface + # serr_out=dut.serr_out, + # hip_enter_err_mode=dut.hip_enter_err_mode, + # app_err_valid=dut.app_err_valid, + # app_err_hdr=dut.app_err_hdr, + # app_err_info=dut.app_err_info, + # app_err_func_num=dut.app_err_func_num, + + # Configuration output + tl_cfg_func=dut.tl_cfg_func, + tl_cfg_add=dut.tl_cfg_add, + tl_cfg_ctl=dut.tl_cfg_ctl, + + # Configuration extension bus + # ceb_req=dut.ceb_req, + # ceb_ack=dut.ceb_ack, + # ceb_addr=dut.ceb_addr, + # ceb_din=dut.ceb_din, + # ceb_dout=dut.ceb_dout, + # ceb_wr=dut.ceb_wr, + # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, + # ceb_func_num=dut.ceb_func_num, + # ceb_vf_num=dut.ceb_vf_num, + # ceb_vf_active=dut.ceb_vf_active, + + # Hard IP reconfiguration interface + # hip_reconfig_clk=dut.hip_reconfig_clk, + # hip_reconfig_address=dut.hip_reconfig_address, + # hip_reconfig_read=dut.hip_reconfig_read, + # hip_reconfig_readdata=dut.hip_reconfig_readdata, + # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, + # hip_reconfig_write=dut.hip_reconfig_write, + # hip_reconfig_writedata=dut.hip_reconfig_writedata, + # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, + ) + + self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**24) + self.dev.functions[0].configure_bar(2, 2**24) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # enable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0x3) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + tb.log.info("Test DMA block operations") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # disable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0) + + # configure operation (read) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001080, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001084, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001088, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00108c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001090, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001094, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001098, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00109c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001008, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00100c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001010, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001018, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00101c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001000, 1) + + await Timer(2000, 'ns') + + # configure operation (write) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001180, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001184, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001188, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00118c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001190, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001194, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001198, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00119c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001108, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00110c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001110, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001118, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00111c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001100, 1) + + await Timer(2000, 'ns') + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', '..', '..', 'rtl')) + + +@pytest.mark.parametrize("data_width", [256]) +@pytest.mark.parametrize("l_tile", [0, 1]) +def test_example_core_pcie_s10(request, data_width, l_tile): + dut = "example_core_pcie_s10" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "example_core_pcie.v"), + os.path.join(rtl_dir, "example_core.v"), + os.path.join(rtl_dir, "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_rx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_if_tx.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_s10_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['SEG_COUNT'] = 2 if data_width == 512 else 1 + parameters['SEG_DATA_WIDTH'] = data_width // parameters['SEG_COUNT'] + parameters['SEG_EMPTY_WIDTH'] = ((parameters['SEG_DATA_WIDTH'] // 32) - 1).bit_length() + parameters['TX_SEQ_NUM_WIDTH'] = 6 + parameters['TX_SEQ_NUM_ENABLE'] = 1 + parameters['L_TILE'] = l_tile + parameters['PCIE_TAG_COUNT'] = 256 + parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT'] + parameters['READ_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['READ_TX_FC_ENABLE'] = 1 + parameters['WRITE_OP_TABLE_SIZE'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['WRITE_TX_LIMIT'] = 2**parameters['TX_SEQ_NUM_WIDTH'] + parameters['WRITE_TX_FC_ENABLE'] = 1 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie_us/Makefile b/fpga/lib/pcie/example/common/tb/example_core_pcie_us/Makefile new file mode 100644 index 000000000..1da8e0c6c --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie_us/Makefile @@ -0,0 +1,140 @@ +# Copyright (c) 2021 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 = example_core_pcie_us +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/example_core.v +VERILOG_SOURCES += ../../rtl/axi_ram.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_if.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_if_rc.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_if_rq.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_if_cq.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_if_cc.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../../../rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../../../rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../../../rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../../../rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../../../rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../../../rtl/dma_psdpram.v +VERILOG_SOURCES += ../../../../rtl/arbiter.v +VERILOG_SOURCES += ../../../../rtl/priority_encoder.v +VERILOG_SOURCES += ../../../../rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= $(if $(filter-out 60,$(PARAM_AXIS_PCIE_RQ_USER_WIDTH)),6,4) +export PARAM_RQ_SEQ_NUM_ENABLE ?= 1 +export PARAM_PCIE_TAG_COUNT ?= 256 +export PARAM_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT) +export PARAM_READ_TX_LIMIT ?= $(shell echo "$$(( 1 << ($(PARAM_RQ_SEQ_NUM_WIDTH)-1) ))" ) +export PARAM_READ_TX_FC_ENABLE ?= 1 +export PARAM_WRITE_OP_TABLE_SIZE ?= $(shell echo "$$(( 1 << ($(PARAM_RQ_SEQ_NUM_WIDTH)-1) ))" ) +export PARAM_WRITE_TX_LIMIT ?= $(shell echo "$$(( 1 << ($(PARAM_RQ_SEQ_NUM_WIDTH)-1) ))" ) +export PARAM_WRITE_TX_FC_ENABLE ?= 1 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).READ_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).WRITE_BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GREAD_OP_TABLE_SIZE=$(PARAM_READ_OP_TABLE_SIZE) + COMPILE_ARGS += -GREAD_TX_LIMIT=$(PARAM_READ_TX_LIMIT) + COMPILE_ARGS += -GREAD_TX_FC_ENABLE=$(PARAM_READ_TX_FC_ENABLE) + COMPILE_ARGS += -GWRITE_OP_TABLE_SIZE=$(PARAM_WRITE_OP_TABLE_SIZE) + COMPILE_ARGS += -GWRITE_TX_LIMIT=$(PARAM_WRITE_TX_LIMIT) + COMPILE_ARGS += -GWRITE_TX_FC_ENABLE=$(PARAM_WRITE_TX_FC_ENABLE) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/common/tb/example_core_pcie_us/test_example_core_pcie_us.py b/fpga/lib/pcie/example/common/tb/example_core_pcie_us/test_example_core_pcie_us.py new file mode 100644 index 000000000..b371ff0fc --- /dev/null +++ b/fpga/lib/pcie/example/common/tb/example_core_pcie_us/test_example_core_pcie_us.py @@ -0,0 +1,497 @@ +""" + +Copyright (c) 2021 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 + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.axi import AxiStreamBus +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + # pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), + + # Completer reQuest Interface + cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**24) + self.dev.functions[0].configure_bar(2, 2**24) + + # monitor error outputs + self.status_error_cor_asserted = False + self.status_error_uncor_asserted = False + cocotb.fork(self._run_monitor_status_error_cor()) + cocotb.fork(self._run_monitor_status_error_uncor()) + + async def _run_monitor_status_error_cor(self): + while True: + await RisingEdge(self.dut.status_error_cor) + self.log.info("status_error_cor (correctable error) was asserted") + self.status_error_cor_asserted = True + + async def _run_monitor_status_error_uncor(self): + while True: + await RisingEdge(self.dut.status_error_uncor) + self.log.info("status_error_uncor (uncorrectable error) was asserted") + self.status_error_uncor_asserted = True + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # enable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0x3) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, 0x100) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + tb.log.info("Test DMA block operations") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + # disable interrupts + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000008, 0) + + # configure operation (read) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001080, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001084, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001088, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00108c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001090, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001094, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001098, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00109c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0010dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001008, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00100c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001010, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001018, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00101c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001000, 1) + + await Timer(2000, 'ns') + + # configure operation (write) + # DMA base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001180, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001184, (mem_base+0x0000 >> 32) & 0xffffffff) + # DMA offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001188, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00118c, 0) + # DMA offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001190, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001194, 0) + # DMA stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001198, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00119c, 0) + # RAM base address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c0, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c4, 0) + # RAM offset address + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011c8, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011cc, 0) + # RAM offset mask + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d0, 0x000003ff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d4, 0) + # RAM stride + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011d8, 256) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x0011dc, 0) + # clear cycle count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001108, 0) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00110c, 0) + # block length + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001110, 256) + # block count + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001118, 32) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00111c, 0) + # start + await tb.rc.mem_write_dword(dev_pf0_bar0+0x001100, 1) + + await Timer(2000, 'ns') + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', '..', '..', 'rtl')) + + +@pytest.mark.parametrize("axis_pcie_data_width", [64, 128, 256, 512]) +def test_example_core_pcie_us(request, axis_pcie_data_width): + dut = "example_core_pcie_us" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "example_core_pcie.v"), + os.path.join(rtl_dir, "example_core.v"), + os.path.join(rtl_dir, "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = axis_pcie_data_width + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 if parameters['AXIS_PCIE_RQ_USER_WIDTH'] == 60 else 6 + parameters['RQ_SEQ_NUM_ENABLE'] = 1 + parameters['PCIE_TAG_COUNT'] = 256 + parameters['READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT'] + parameters['READ_TX_LIMIT'] = 2**(parameters['RQ_SEQ_NUM_WIDTH']-1) + parameters['READ_TX_FC_ENABLE'] = 1 + parameters['WRITE_OP_TABLE_SIZE'] = 2**(parameters['RQ_SEQ_NUM_WIDTH']-1) + parameters['WRITE_TX_LIMIT'] = 2**(parameters['RQ_SEQ_NUM_WIDTH']-1) + parameters['WRITE_TX_FC_ENABLE'] = 1 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/fb2CG/fpga/README.md b/fpga/lib/pcie/example/fb2CG/fpga/README.md new file mode 100644 index 000000000..1846fe1b0 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/README.md @@ -0,0 +1,19 @@ +# Verilog PCIe fb2CG@KU15P Example Design + +## Introduction + +This example design targets the Silicom fb2CG@KU15P FPGA board. + +The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design. + +* FPGA: xcku15p-ffve1760-2-e + +## How to build + +Run `make` to build. Ensure that the Xilinx Vivado toolchain components are in PATH. + +Run `make` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled. + +## How to test + +Run `make program` to program the fb2CG@KU15P board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output. diff --git a/fpga/lib/pcie/example/fb2CG/fpga/common/vivado.mk b/fpga/lib/pcie/example/fb2CG/fpga/common/vivado.mk new file mode 100644 index 000000000..d47a43947 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/common/vivado.mk @@ -0,0 +1,126 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: fpga vivado tmpclean clean distclean + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(SYN_FILES))) $(filter /% ./%,$(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(INC_FILES))) $(filter /% ./%,$(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XCI_FILES))) $(filter /% ./%,$(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(IP_TCL_FILES))) $(filter /% ./%,$(IP_TCL_FILES)) +CONFIG_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(CONFIG_TCL_FILES))) $(filter /% ./%,$(CONFIG_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XDC_FILES))) $(filter /% ./%,$(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean:: + -rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean:: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean:: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $(FPGA_TOP)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done + +update_config.tcl: $(CONFIG_TCL_FILES_REL) + echo "open_project -quiet $(FPGA_TOP).xpr" > $@ + for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(FPGA_TOP).xpr: create_project.tcl update_config.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) $(CONFIG_TCL_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/pcie/example/fb2CG/fpga/driver b/fpga/lib/pcie/example/fb2CG/fpga/driver new file mode 120000 index 000000000..4a54c76b5 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/driver @@ -0,0 +1 @@ +../../common/driver/example/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/fb2CG/fpga/fpga.xdc b/fpga/lib/pcie/example/fb2CG/fpga/fpga.xdc new file mode 100644 index 000000000..3ad9007db --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/fpga.xdc @@ -0,0 +1,266 @@ +# XDC constraints for the fb2CG@KU15P +# part: xcku15p-ffve1760-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN disable [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.CONFIGRATE 85.0 [current_design] +set_property CONFIG_MODE SPIx4 [current_design] +set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] + +# System clocks +# init clock 50 MHz +#set_property -dict {LOC E7 IOSTANDARD LVCMOS18} [get_ports init_clk] +#create_clock -period 20.000 -name init_clk [get_ports init_clk] + +# E7 is not a global clock capable input, so need to set CLOCK_DEDICATED_ROUTE to satisfy DRC +#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets init_clk_ibuf_inst/O] +#set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets init_clk_bufg] + +# DDR4 refclk1 +#set_property -dict {LOC AT32 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk1_p] +#set_property -dict {LOC AU32 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk1_n] +#create_clock -period 3.750 -name clk_ddr4_refclk1 [get_ports clk_ddr4_refclk1_p] + +# DDR4 refclk2 +#set_property -dict {LOC G29 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk2_p] +#set_property -dict {LOC G28 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk2_n] +#create_clock -period 3.750 -name clk_ddr4_refclk2 [get_ports clk_ddr4_refclk1_p] + +# LEDs +set_property -dict {LOC C4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_d] +set_property -dict {LOC B3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_ld] +set_property -dict {LOC G3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_clk] +set_property -dict {LOC C5 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {led_bmc[0]}] +set_property -dict {LOC C6 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {led_bmc[1]}] +set_property -dict {LOC D3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports {led_exp[0]}] +set_property -dict {LOC D4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports {led_exp[1]}] + +set_false_path -to [get_ports {led_sreg_d led_sreg_ld led_sreg_clk led_bmc[*] led_exp[*]}] +set_output_delay 0 [get_ports {led_sreg_d led_sreg_ld led_sreg_clk led_bmc[*] led_exp[*]}] + +# GPIO +#set_property -dict {LOC B4 IOSTANDARD LVCMOS33} [get_ports pps_in] ;# from SMA J6 via Q1 (inverted) +#set_property -dict {LOC A4 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 4} [get_ports pps_out] ;# to SMA J6 via U4 and U5, and u.FL J7 (PPS OUT) via U3 +#set_property -dict {LOC A3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports pps_out_en] ; # to U5 IN (connects pps_out to SMA J6 when high) +#set_property -dict {LOC H2 IOSTANDARD LVCMOS33} [get_ports misc_ucoax] ; from u.FL J5 (PPS IN) + +#set_false_path -to [get_ports {pps_out pps_out_en}] +#set_output_delay 0 [get_ports {pps_out pps_out_en}] +#set_false_path -from [get_ports {pps_in}] +#set_input_delay 0 [get_ports {pps_in}] + +# BMC interface +#set_property -dict {LOC D7 IOSTANDARD LVCMOS18} [get_ports bmc_miso] +#set_property -dict {LOC J4 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_nss] +#set_property -dict {LOC B6 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_clk] +#set_property -dict {LOC D5 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_mosi] +#set_property -dict {LOC H4 IOSTANDARD LVCMOS18} [get_ports bmc_int] + +#set_false_path -to [get_ports {bmc_nss bmc_clk bmc_mosi}] +#set_output_delay 0 [get_ports {bmc_nss bmc_clk bmc_mosi}] +#set_false_path -from [get_ports {bmc_miso bmc_int}] +#set_input_delay 0 [get_ports {bmc_miso bmc_int}] + +# Board status +#set_property -dict {LOC J2 IOSTANDARD LVCMOS33} [get_ports {fan_tacho[0]}] +#set_property -dict {LOC J3 IOSTANDARD LVCMOS33} [get_ports {fan_tacho[1]}] +#set_property -dict {LOC A6 IOSTANDARD LVCMOS18} [get_ports {pg[0]}] +#set_property -dict {LOC C7 IOSTANDARD LVCMOS18} [get_ports {pg[1]}] +#set_property -dict {LOC E2 IOSTANDARD LVCMOS33} [get_ports pwrbrk] + +#set_false_path -from [get_ports {pg[*]}] +#set_input_delay 0 [get_ports {pg[*]}] + +# QSFP28 Interfaces +#set_property -dict {LOC Y39 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC Y40 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC Y34 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC Y35 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W41 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W42 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W36 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W37 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V39 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V40 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V34 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V35 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U41 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U42 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U36 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U37 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W32 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_130 from U28 +#set_property -dict {LOC W33 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_130 from U28 +#set_property -dict {LOC B9 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_mod_prsnt_n] +#set_property -dict {LOC A8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_reset_n] +#set_property -dict {LOC A9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_lp_mode] +#set_property -dict {LOC A10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_intr_n] +#set_property -dict {LOC B8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_i2c_scl] +#set_property -dict {LOC B7 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_i2c_sda] + +# 161.1328125 MHz MGT reference clock +#create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p] + +#set_false_path -to [get_ports {qsfp_0_reset_n qsfp_0_lp_mode}] +#set_output_delay 0 [get_ports {qsfp_0_reset_n qsfp_0_lp_mode}] +#set_false_path -from [get_ports {qsfp_0_mod_prsnt_n qsfp_0_intr_n}] +#set_input_delay 0 [get_ports {qsfp_0_mod_prsnt_n qsfp_0_intr_n}] + +#set_false_path -to [get_ports {qsfp_0_i2c_scl qsfp_0_i2c_sda}] +#set_output_delay 0 [get_ports {qsfp_0_i2c_scl qsfp_0_i2c_sda}] +#set_false_path -from [get_ports {qsfp_0_i2c_scl qsfp_0_i2c_sda}] +#set_input_delay 0 [get_ports {qsfp_0_i2c_scl qsfp_0_i2c_sda}] + +#set_property -dict {LOC M39 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC M40 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC M34 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC M35 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L41 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L42 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L36 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L37 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K39 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K40 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K34 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J41 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J42 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J36 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J37 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC P30 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_132 from U28 +#set_property -dict {LOC P31 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_132 from U28 +#set_property -dict {LOC E10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_mod_prsnt_n] +#set_property -dict {LOC C10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_reset_n] +#set_property -dict {LOC D9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_lp_mode] +#set_property -dict {LOC D10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_intr_n] +#set_property -dict {LOC C9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_i2c_scl] +#set_property -dict {LOC D8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_i2c_sda] + +# 161.1328125 MHz MGT reference clock +#create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p] + +#set_false_path -to [get_ports {qsfp_1_reset_n qsfp_1_lp_mode}] +#set_output_delay 0 [get_ports {qsfp_1_reset_n qsfp_1_lp_mode}] +#set_false_path -from [get_ports {qsfp_1_mod_prsnt_n qsfp_1_intr_n}] +#set_input_delay 0 [get_ports {qsfp_1_mod_prsnt_n qsfp_1_intr_n}] + +#set_false_path -to [get_ports {qsfp_1_i2c_scl qsfp_1_i2c_sda}] +#set_output_delay 0 [get_ports {qsfp_1_i2c_scl qsfp_1_i2c_sda}] +#set_false_path -from [get_ports {qsfp_1_i2c_scl qsfp_1_i2c_sda}] +#set_input_delay 0 [get_ports {qsfp_1_i2c_scl qsfp_1_i2c_sda}] + +# Expansion connector +#set_property -dict {LOC AG41} [get_ports {exp_rx_p[0]}] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG42} [get_ports {exp_rx_n[0]}] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG36} [get_ports {exp_tx_p[0]}] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG37} [get_ports {exp_tx_n[0]}] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH39} [get_ports {exp_rx_p[1]}] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH40} [get_ports {exp_rx_n[1]}] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH34} [get_ports {exp_tx_p[1]}] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH35} [get_ports {exp_tx_n[1]}] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AJ41} [get_ports {exp_rx_p[2]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ42} [get_ports {exp_rx_n[2]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ36} [get_ports {exp_tx_p[2]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ37} [get_ports {exp_tx_n[2]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK39} [get_ports {exp_rx_p[3]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK40} [get_ports {exp_rx_n[3]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK34} [get_ports {exp_tx_p[3]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK35} [get_ports {exp_tx_n[3]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL41} [get_ports {exp_rx_p[4]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL42} [get_ports {exp_rx_n[4]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL36} [get_ports {exp_tx_p[4]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL37} [get_ports {exp_tx_n[4]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM39} [get_ports {exp_rx_p[5]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM40} [get_ports {exp_rx_n[5]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM34} [get_ports {exp_tx_p[5]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM35} [get_ports {exp_tx_n[5]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL32} [get_ports exp_refclk_0_p] ;# MGTREFCLK0P_128 from U28 +#set_property -dict {LOC AL33} [get_ports exp_refclk_0_n] ;# MGTREFCLK0N_128 from U28 +#set_property -dict {LOC AG32} [get_ports exp_refclk_1_p] ;# MGTREFCLK0P_127 from U28 +#set_property -dict {LOC AG33} [get_ports exp_refclk_1_n] ;# MGTREFCLK0N_127 from U28 +#set_property -dict {LOC E3 IOSTANDARD LVCMOS33} [get_ports {exp_gpio[0]}] +#set_property -dict {LOC F3 IOSTANDARD LVCMOS33} [get_ports {exp_gpio[1]}] + +# 161.1328125 MHz MGT reference clock +#create_clock -period 6.206 -name exp_refclk_0 [get_ports exp_refclk_0_p] +#create_clock -period 6.206 -name exp_refclk_1 [get_ports exp_refclk_1_p] + +# PCIe Interface +set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[0]}] ;# MGTHRXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[0]}] ;# MGTHRXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AG6 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AG5 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AH4 } [get_ports {pcie_rx_p[1]}] ;# MGTHRXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AH3 } [get_ports {pcie_rx_n[1]}] ;# MGTHRXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AH8 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AH7 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[2]}] ;# MGTHRXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[2]}] ;# MGTHRXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AJ6 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AJ5 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[3]}] ;# MGTHRXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[3]}] ;# MGTHRXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AK8 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AK7 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[4]}] ;# MGTHRXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[4]}] ;# MGTHRXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AL6 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AL5 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[5]}] ;# MGTHRXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[5]}] ;# MGTHRXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AM8 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AM7 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[6]}] ;# MGTHRXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[6]}] ;# MGTHRXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AN6 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AN5 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[7]}] ;# MGTHRXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[7]}] ;# MGTHRXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AP8 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AP7 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[8]}] ;# MGTHRXP3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[8]}] ;# MGTHRXN3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AR6 } [get_ports {pcie_tx_p[8]}] ;# MGTHTXP3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AR5 } [get_ports {pcie_tx_n[8]}] ;# MGTHTXN3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[9]}] ;# MGTHRXP2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[9]}] ;# MGTHRXN2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AT8 } [get_ports {pcie_tx_p[9]}] ;# MGTHTXP2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AT7 } [get_ports {pcie_tx_n[9]}] ;# MGTHTXN2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[10]}] ;# MGTHRXP1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[10]}] ;# MGTHRXN1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AU6 } [get_ports {pcie_tx_p[10]}] ;# MGTHTXP1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AU5 } [get_ports {pcie_tx_n[10]}] ;# MGTHTXN1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[11]}] ;# MGTHRXP0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[11]}] ;# MGTHRXN0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AV8 } [get_ports {pcie_tx_p[11]}] ;# MGTHTXP0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AV7 } [get_ports {pcie_tx_n[11]}] ;# MGTHTXN0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[12]}] ;# MGTHRXP3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[12]}] ;# MGTHRXN3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AW6 } [get_ports {pcie_tx_p[12]}] ;# MGTHTXP3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AW5 } [get_ports {pcie_tx_n[12]}] ;# MGTHTXN3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[13]}] ;# MGTHRXP2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[13]}] ;# MGTHRXN2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AY8 } [get_ports {pcie_tx_p[13]}] ;# MGTHTXP2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AY7 } [get_ports {pcie_tx_n[13]}] ;# MGTHTXN2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTHRXP1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTHRXN1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BA6 } [get_ports {pcie_tx_p[14]}] ;# MGTHTXP1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BA5 } [get_ports {pcie_tx_n[14]}] ;# MGTHTXN1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[15]}] ;# MGTHRXP0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[15]}] ;# MGTHRXN0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BB8 } [get_ports {pcie_tx_p[15]}] ;# MGTHTXP0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC BB7 } [get_ports {pcie_tx_n[15]}] ;# MGTHTXN0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +set_property -dict {LOC AN10} [get_ports pcie_refclk_p] ;# MGTREFCLK0P_226 +set_property -dict {LOC AN9 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_226 +set_property -dict {LOC G1 IOSTANDARD LVCMOS33 PULLUP true} [get_ports pcie_rst_n] + +# 100 MHz MGT reference clock +create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p] + +set_false_path -from [get_ports {pcie_rst_n}] +set_input_delay 0 [get_ports {pcie_rst_n}] diff --git a/fpga/lib/pcie/example/fb2CG/fpga/fpga/Makefile b/fpga/lib/pcie/example/fb2CG/fpga/fpga/Makefile new file mode 100644 index 000000000..5502084f4 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/fpga/Makefile @@ -0,0 +1,95 @@ + +# FPGA settings +FPGA_PART = xcku15p-ffve1760-2-e +FPGA_TOP = fpga +FPGA_ARCH = kintexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/led_sreg_driver.v +SYN_FILES += rtl/common/example_core_pcie_us.v +SYN_FILES += rtl/common/example_core_pcie.v +SYN_FILES += rtl/common/example_core.v +SYN_FILES += rtl/common/axi_ram.v +SYN_FILES += lib/pcie/rtl/pcie_us_if.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v +SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v +SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v +SYN_FILES += lib/pcie/rtl/pcie_us_msi.v +SYN_FILES += lib/pcie/rtl/pcie_axil_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v +SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v +SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v +SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v +SYN_FILES += lib/pcie/rtl/dma_psdpram.v +SYN_FILES += lib/pcie/rtl/arbiter.v +SYN_FILES += lib/pcie/rtl/priority_encoder.v +SYN_FILES += lib/pcie/rtl/pulse_merge.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += led.tcl + +# IP +IP_TCL_FILES = ip/pcie4_uscale_plus_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +%.mcs %.prm: %.bit + echo "write_cfgmem -force -format mcs -size 64 -interface SPIx4 -loadbit {up 0x0000000 $*.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 {mt25qu512-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 + diff --git a/fpga/lib/pcie/example/fb2CG/fpga/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/fb2CG/fpga/ip/pcie4_uscale_plus_0.tcl new file mode 100644 index 000000000..75f0eddca --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/ip/pcie4_uscale_plus_0.tcl @@ -0,0 +1,28 @@ + +create_ip -name pcie4_uscale_plus -vendor xilinx.com -library ip -module_name pcie4_uscale_plus_0 + +set_property -dict [list \ + CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \ + CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X16} \ + CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \ + CONFIG.axisten_if_enable_client_tag {true} \ + CONFIG.axisten_if_width {512_bit} \ + CONFIG.axisten_freq {250} \ + CONFIG.PF0_CLASS_CODE {058000} \ + CONFIG.PF0_DEVICE_ID {0001} \ + CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ + CONFIG.PF0_SUBSYSTEM_ID {a00e} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1c2c} \ + CONFIG.pf0_bar0_64bit {true} \ + CONFIG.pf0_bar0_prefetchable {true} \ + CONFIG.pf0_bar0_scale {Megabytes} \ + CONFIG.pf0_bar0_size {16} \ + CONFIG.pf0_bar2_64bit {true} \ + CONFIG.pf0_bar2_prefetchable {true} \ + CONFIG.pf0_bar2_enabled {true} \ + CONFIG.pf0_bar2_type {Memory} \ + CONFIG.pf0_bar2_scale {Megabytes} \ + CONFIG.pf0_bar2_size {16} \ + CONFIG.vendor_id {1234} \ + CONFIG.en_msi_per_vec_masking {true} \ +] [get_ips pcie4_uscale_plus_0] diff --git a/fpga/lib/pcie/example/fb2CG/fpga/led.tcl b/fpga/lib/pcie/example/fb2CG/fpga/led.tcl new file mode 100644 index 000000000..1e1bd643d --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/led.tcl @@ -0,0 +1,12 @@ +# Timing constraints for led_sreg_driver + +foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == led_sreg_driver || REF_NAME == led_sreg_driver)}] { + puts "Inserting timing constraints for led_sreg_driver instance $inst" + + set select_ffs [get_cells "$inst/led_sync_reg_1_reg[*] $inst/led_sync_reg_2_reg[*]"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + set_false_path -to [get_pins "$inst/led_sync_reg_1_reg[*]/D"] + } +} diff --git a/fpga/lib/pcie/example/fb2CG/fpga/lib/pcie b/fpga/lib/pcie/example/fb2CG/fpga/lib/pcie new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/lib/pcie @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/common b/fpga/lib/pcie/example/fb2CG/fpga/rtl/common new file mode 120000 index 000000000..e60fada70 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/common @@ -0,0 +1 @@ +../../../common/rtl/ \ No newline at end of file diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga.v b/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga.v new file mode 100644 index 000000000..29740ca85 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga.v @@ -0,0 +1,490 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga ( + /* + * GPIO + */ + output wire led_sreg_d, + output wire led_sreg_ld, + output wire led_sreg_clk, + output wire [1:0] led_bmc, + output wire [1:0] led_exp, + + /* + * PCI express + */ + input wire [15:0] pcie_rx_p, + input wire [15:0] pcie_rx_n, + output wire [15:0] pcie_tx_p, + output wire [15:0] pcie_tx_n, + input wire pcie_refclk_p, + input wire pcie_refclk_n, + input wire pcie_rst_n +); + +parameter AXIS_PCIE_DATA_WIDTH = 512; +parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); +parameter AXIS_PCIE_RC_USER_WIDTH = 161; +parameter AXIS_PCIE_RQ_USER_WIDTH = 137; +parameter AXIS_PCIE_CQ_USER_WIDTH = 183; +parameter AXIS_PCIE_CC_USER_WIDTH = 81; + +parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6; +parameter RQ_SEQ_NUM_ENABLE = 1; + +parameter PCIE_TAG_COUNT = 64; +parameter BAR0_APERTURE = 24; +parameter BAR2_APERTURE = 24; + +// PCIe +wire pcie_user_clk; +wire pcie_user_reset; + +wire pcie_sys_clk; +wire pcie_sys_clk_gt; + +IBUFDS_GTE4 #( + .REFCLK_HROW_CK_SEL(2'b00) +) +ibufds_gte4_pcie_mgt_refclk_inst ( + .I (pcie_refclk_p), + .IB (pcie_refclk_n), + .CEB (1'b0), + .O (pcie_sys_clk_gt), + .ODIV2 (pcie_sys_clk) +); + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rq_tkeep; +wire axis_rq_tlast; +wire axis_rq_tready; +wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] axis_rq_tuser; +wire axis_rq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rc_tkeep; +wire axis_rc_tlast; +wire axis_rc_tready; +wire [AXIS_PCIE_RC_USER_WIDTH-1:0] axis_rc_tuser; +wire axis_rc_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cq_tkeep; +wire axis_cq_tlast; +wire axis_cq_tready; +wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] axis_cq_tuser; +wire axis_cq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cc_tkeep; +wire axis_cc_tlast; +wire axis_cc_tready; +wire [AXIS_PCIE_CC_USER_WIDTH-1:0] axis_cc_tuser; +wire axis_cc_tvalid; + +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num0; +wire pcie_rq_seq_num_vld0; +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num1; +wire pcie_rq_seq_num_vld1; + +// ila_0 rq_ila ( +// .clk(pcie_user_clk), +// .probe0(axis_rq_tdata), +// .probe1(axis_rq_tkeep), +// .probe2(axis_rq_tlast), +// .probe3(axis_rq_tready), +// .probe4(axis_rq_tuser), +// .probe5(axis_rq_tvalid) +// ); + +// ila_0 rc_ila ( +// .clk(pcie_user_clk), +// .probe0(axis_rc_tdata), +// .probe1(axis_rc_tkeep), +// .probe2(axis_rc_tlast), +// .probe3(axis_rc_tready), +// .probe4(axis_rc_tuser), +// .probe5(axis_rc_tvalid) +// ); + +wire [2:0] cfg_max_payload; +wire [2:0] cfg_max_read_req; + +wire [9:0] cfg_mgmt_addr; +wire [7:0] cfg_mgmt_function_number; +wire cfg_mgmt_write; +wire [31:0] cfg_mgmt_write_data; +wire [3:0] cfg_mgmt_byte_enable; +wire cfg_mgmt_read; +wire [31:0] cfg_mgmt_read_data; +wire cfg_mgmt_read_write_done; + +wire [7:0] cfg_fc_ph; +wire [11:0] cfg_fc_pd; +wire [7:0] cfg_fc_nph; +wire [11:0] cfg_fc_npd; +wire [7:0] cfg_fc_cplh; +wire [11:0] cfg_fc_cpld; +wire [2:0] cfg_fc_sel; + +wire [3:0] cfg_interrupt_msi_enable; +wire [11:0] cfg_interrupt_msi_mmenable; +wire cfg_interrupt_msi_mask_update; +wire [31:0] cfg_interrupt_msi_data; +wire [3:0] cfg_interrupt_msi_select; +wire [31:0] cfg_interrupt_msi_int; +wire [31:0] cfg_interrupt_msi_pending_status; +wire cfg_interrupt_msi_pending_status_data_enable; +wire [3:0] cfg_interrupt_msi_pending_status_function_num; +wire cfg_interrupt_msi_sent; +wire cfg_interrupt_msi_fail; +wire [2:0] cfg_interrupt_msi_attr; +wire cfg_interrupt_msi_tph_present; +wire [1:0] cfg_interrupt_msi_tph_type; +wire [8:0] cfg_interrupt_msi_tph_st_tag; +wire [3:0] cfg_interrupt_msi_function_number; + +wire status_error_cor; +wire status_error_uncor; + +pcie4_uscale_plus_0 +pcie4_uscale_plus_inst ( + .pci_exp_txn(pcie_tx_n), + .pci_exp_txp(pcie_tx_p), + .pci_exp_rxn(pcie_rx_n), + .pci_exp_rxp(pcie_rx_p), + .user_clk(pcie_user_clk), + .user_reset(pcie_user_reset), + .user_lnk_up(), + + .s_axis_rq_tdata(axis_rq_tdata), + .s_axis_rq_tkeep(axis_rq_tkeep), + .s_axis_rq_tlast(axis_rq_tlast), + .s_axis_rq_tready(axis_rq_tready), + .s_axis_rq_tuser(axis_rq_tuser), + .s_axis_rq_tvalid(axis_rq_tvalid), + + .m_axis_rc_tdata(axis_rc_tdata), + .m_axis_rc_tkeep(axis_rc_tkeep), + .m_axis_rc_tlast(axis_rc_tlast), + .m_axis_rc_tready(axis_rc_tready), + .m_axis_rc_tuser(axis_rc_tuser), + .m_axis_rc_tvalid(axis_rc_tvalid), + + .m_axis_cq_tdata(axis_cq_tdata), + .m_axis_cq_tkeep(axis_cq_tkeep), + .m_axis_cq_tlast(axis_cq_tlast), + .m_axis_cq_tready(axis_cq_tready), + .m_axis_cq_tuser(axis_cq_tuser), + .m_axis_cq_tvalid(axis_cq_tvalid), + + .s_axis_cc_tdata(axis_cc_tdata), + .s_axis_cc_tkeep(axis_cc_tkeep), + .s_axis_cc_tlast(axis_cc_tlast), + .s_axis_cc_tready(axis_cc_tready), + .s_axis_cc_tuser(axis_cc_tuser), + .s_axis_cc_tvalid(axis_cc_tvalid), + + .pcie_rq_seq_num0(pcie_rq_seq_num0), + .pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0), + .pcie_rq_seq_num1(pcie_rq_seq_num1), + .pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1), + .pcie_rq_tag0(), + .pcie_rq_tag1(), + .pcie_rq_tag_av(), + .pcie_rq_tag_vld0(), + .pcie_rq_tag_vld1(), + + .pcie_tfc_nph_av(), + .pcie_tfc_npd_av(), + + .pcie_cq_np_req(1'b1), + .pcie_cq_np_req_count(), + + .cfg_phy_link_down(), + .cfg_phy_link_status(), + .cfg_negotiated_width(), + .cfg_current_speed(), + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_function_status(), + .cfg_function_power_state(), + .cfg_vf_status(), + .cfg_vf_power_state(), + .cfg_link_power_state(), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + .cfg_mgmt_debug_access(1'b0), + + .cfg_err_cor_out(), + .cfg_err_nonfatal_out(), + .cfg_err_fatal_out(), + .cfg_local_error_valid(), + .cfg_local_error_out(), + .cfg_ltssm_state(), + .cfg_rx_pm_state(), + .cfg_tx_pm_state(), + .cfg_rcb_status(), + .cfg_obff_enable(), + .cfg_pl_status_change(), + .cfg_tph_requester_enable(), + .cfg_tph_st_mode(), + .cfg_vf_tph_requester_enable(), + .cfg_vf_tph_st_mode(), + + .cfg_msg_received(), + .cfg_msg_received_data(), + .cfg_msg_received_type(), + .cfg_msg_transmit(1'b0), + .cfg_msg_transmit_type(3'd0), + .cfg_msg_transmit_data(32'd0), + .cfg_msg_transmit_done(), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_dsn(64'd0), + + .cfg_bus_number(), + + .cfg_power_state_change_ack(1'b1), + .cfg_power_state_change_interrupt(), + + .cfg_err_cor_in(status_error_cor), + .cfg_err_uncor_in(status_error_uncor), + .cfg_flr_in_process(), + .cfg_flr_done(4'd0), + .cfg_vf_flr_in_process(), + .cfg_vf_flr_func_num(8'd0), + .cfg_vf_flr_done(8'd0), + + .cfg_link_training_enable(1'b1), + + .cfg_interrupt_int(4'd0), + .cfg_interrupt_pending(4'd0), + .cfg_interrupt_sent(), + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_pm_aspm_l1_entry_reject(1'b0), + .cfg_pm_aspm_tx_l0s_entry_disable(1'b0), + + .cfg_hot_reset_out(), + + .cfg_config_space_enable(1'b1), + .cfg_req_pm_transition_l23_ready(1'b0), + .cfg_hot_reset_in(1'b0), + + .cfg_ds_port_number(8'd0), + .cfg_ds_bus_number(8'd0), + .cfg_ds_device_number(5'd0), + + .sys_clk(pcie_sys_clk), + .sys_clk_gt(pcie_sys_clk_gt), + .sys_reset(pcie_rst_n), + + .phy_rdy_out() +); + +// GPIO +wire [7:0] led_red; +wire [7:0] led_green; +wire [15:0] led_merged; + +assign led_merged[0] = led_red[0]; +assign led_merged[1] = led_green[0]; +assign led_merged[2] = led_red[1]; +assign led_merged[3] = led_green[1]; +assign led_merged[4] = led_red[2]; +assign led_merged[5] = led_green[2]; +assign led_merged[6] = led_red[3]; +assign led_merged[7] = led_green[3]; +assign led_merged[8] = led_red[4]; +assign led_merged[9] = led_green[4]; +assign led_merged[10] = led_red[5]; +assign led_merged[11] = led_green[5]; +assign led_merged[12] = led_red[6]; +assign led_merged[13] = led_green[6]; +assign led_merged[14] = led_red[7]; +assign led_merged[15] = led_green[7]; + +led_sreg_driver #( + .COUNT(16), + .INVERT(1), + .PRESCALE(63) +) +led_sreg_driver_inst ( + .clk(pcie_user_clk), + .rst(pcie_user_reset), + + .led(led_merged), + + .sreg_d(led_sreg_d), + .sreg_ld(led_sreg_ld), + .sreg_clk(led_sreg_clk) +); + +fpga_core #( + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +core_inst ( + /* + * Clock: 250 MHz + * Synchronous reset + */ + .clk(pcie_user_clk), + .rst(pcie_user_reset), + /* + * GPIO + */ + .led_red(led_red), + .led_green(led_green), + .led_bmc(led_bmc), + .led_exp(led_exp), + /* + * PCIe + */ + .m_axis_rq_tdata(axis_rq_tdata), + .m_axis_rq_tkeep(axis_rq_tkeep), + .m_axis_rq_tlast(axis_rq_tlast), + .m_axis_rq_tready(axis_rq_tready), + .m_axis_rq_tuser(axis_rq_tuser), + .m_axis_rq_tvalid(axis_rq_tvalid), + + .s_axis_rc_tdata(axis_rc_tdata), + .s_axis_rc_tkeep(axis_rc_tkeep), + .s_axis_rc_tlast(axis_rc_tlast), + .s_axis_rc_tready(axis_rc_tready), + .s_axis_rc_tuser(axis_rc_tuser), + .s_axis_rc_tvalid(axis_rc_tvalid), + + .s_axis_cq_tdata(axis_cq_tdata), + .s_axis_cq_tkeep(axis_cq_tkeep), + .s_axis_cq_tlast(axis_cq_tlast), + .s_axis_cq_tready(axis_cq_tready), + .s_axis_cq_tuser(axis_cq_tuser), + .s_axis_cq_tvalid(axis_cq_tvalid), + + .m_axis_cc_tdata(axis_cc_tdata), + .m_axis_cc_tkeep(axis_cc_tkeep), + .m_axis_cc_tlast(axis_cc_tlast), + .m_axis_cc_tready(axis_cc_tready), + .m_axis_cc_tuser(axis_cc_tuser), + .m_axis_cc_tvalid(axis_cc_tvalid), + + .s_axis_rq_seq_num_0(pcie_rq_seq_num0), + .s_axis_rq_seq_num_valid_0(pcie_rq_seq_num_vld0), + .s_axis_rq_seq_num_1(pcie_rq_seq_num1), + .s_axis_rq_seq_num_valid_1(pcie_rq_seq_num_vld1), + + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga_core.v b/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..37065c74a --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/fpga_core.v @@ -0,0 +1,276 @@ +/* + +Copyright (c) 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter AXIS_PCIE_DATA_WIDTH = 512, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = 161, + parameter AXIS_PCIE_RQ_USER_WIDTH = 137, + parameter AXIS_PCIE_CQ_USER_WIDTH = 183, + parameter AXIS_PCIE_CC_USER_WIDTH = 81, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter RQ_SEQ_NUM_ENABLE = 1, + parameter PCIE_TAG_COUNT = 64, + parameter BAR0_APERTURE = 24, + parameter BAR2_APERTURE = 24 +) +( + /* + * Clock: 250 MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [7:0] led_red, + output wire [7:0] led_green, + output wire [1:0] led_bmc, + output wire [1:0] led_exp, + + /* + * PCIe + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep, + output wire m_axis_rq_tlast, + input wire m_axis_rq_tready, + output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser, + output wire m_axis_rq_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep, + input wire s_axis_rc_tlast, + output wire s_axis_rc_tready, + input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser, + input wire s_axis_rc_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep, + input wire s_axis_cq_tlast, + output wire s_axis_cq_tready, + input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser, + input wire s_axis_cq_tvalid, + + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep, + output wire m_axis_cc_tlast, + input wire m_axis_cc_tready, + output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser, + output wire m_axis_cc_tvalid, + + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0, + input wire s_axis_rq_seq_num_valid_0, + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1, + input wire s_axis_rq_seq_num_valid_1, + + input wire [2:0] cfg_max_payload, + input wire [2:0] cfg_max_read_req, + + output wire [9:0] cfg_mgmt_addr, + output wire [7:0] cfg_mgmt_function_number, + output wire cfg_mgmt_write, + output wire [31:0] cfg_mgmt_write_data, + output wire [3:0] cfg_mgmt_byte_enable, + output wire cfg_mgmt_read, + input wire [31:0] cfg_mgmt_read_data, + input wire cfg_mgmt_read_write_done, + + input wire [7:0] cfg_fc_ph, + input wire [11:0] cfg_fc_pd, + input wire [7:0] cfg_fc_nph, + input wire [11:0] cfg_fc_npd, + input wire [7:0] cfg_fc_cplh, + input wire [11:0] cfg_fc_cpld, + output wire [2:0] cfg_fc_sel, + + input wire [3:0] cfg_interrupt_msi_enable, + input wire [11:0] cfg_interrupt_msi_mmenable, + input wire cfg_interrupt_msi_mask_update, + input wire [31:0] cfg_interrupt_msi_data, + output wire [3:0] cfg_interrupt_msi_select, + output wire [31:0] cfg_interrupt_msi_int, + output wire [31:0] cfg_interrupt_msi_pending_status, + output wire cfg_interrupt_msi_pending_status_data_enable, + output wire [3:0] cfg_interrupt_msi_pending_status_function_num, + input wire cfg_interrupt_msi_sent, + input wire cfg_interrupt_msi_fail, + output wire [2:0] cfg_interrupt_msi_attr, + output wire cfg_interrupt_msi_tph_present, + output wire [1:0] cfg_interrupt_msi_tph_type, + output wire [8:0] cfg_interrupt_msi_tph_st_tag, + output wire [3:0] cfg_interrupt_msi_function_number, + + output wire status_error_cor, + output wire status_error_uncor +); + +assign led_red = 8'd0; +assign led_green = 8'd0; +assign led_bmc = 2'b00; +assign led_exp = 2'b11; + +example_core_pcie_us #( + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .READ_OP_TABLE_SIZE(PCIE_TAG_COUNT), + .READ_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)), + .READ_TX_FC_ENABLE(1), + .WRITE_OP_TABLE_SIZE(2**(RQ_SEQ_NUM_WIDTH-1)), + .WRITE_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)), + .WRITE_TX_FC_ENABLE(1), + .BAR0_APERTURE(BAR0_APERTURE), + .BAR2_APERTURE(BAR2_APERTURE) +) +example_core_pcie_us_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI input (RC) + */ + .s_axis_rc_tdata(s_axis_rc_tdata), + .s_axis_rc_tkeep(s_axis_rc_tkeep), + .s_axis_rc_tvalid(s_axis_rc_tvalid), + .s_axis_rc_tready(s_axis_rc_tready), + .s_axis_rc_tlast(s_axis_rc_tlast), + .s_axis_rc_tuser(s_axis_rc_tuser), + + /* + * AXI output (RQ) + */ + .m_axis_rq_tdata(m_axis_rq_tdata), + .m_axis_rq_tkeep(m_axis_rq_tkeep), + .m_axis_rq_tvalid(m_axis_rq_tvalid), + .m_axis_rq_tready(m_axis_rq_tready), + .m_axis_rq_tlast(m_axis_rq_tlast), + .m_axis_rq_tuser(m_axis_rq_tuser), + + /* + * AXI input (CQ) + */ + .s_axis_cq_tdata(s_axis_cq_tdata), + .s_axis_cq_tkeep(s_axis_cq_tkeep), + .s_axis_cq_tvalid(s_axis_cq_tvalid), + .s_axis_cq_tready(s_axis_cq_tready), + .s_axis_cq_tlast(s_axis_cq_tlast), + .s_axis_cq_tuser(s_axis_cq_tuser), + + /* + * AXI output (CC) + */ + .m_axis_cc_tdata(m_axis_cc_tdata), + .m_axis_cc_tkeep(m_axis_cc_tkeep), + .m_axis_cc_tvalid(m_axis_cc_tvalid), + .m_axis_cc_tready(m_axis_cc_tready), + .m_axis_cc_tlast(m_axis_cc_tlast), + .m_axis_cc_tuser(m_axis_cc_tuser), + + /* + * Transmit sequence number input + */ + .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), + .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), + .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), + .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), + + /* + * Flow control + */ + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + /* + * Configuration interface + */ + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + /* + * Interrupt interface + */ + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(8'd0), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * Configuration + */ + .cfg_max_read_req(cfg_max_read_req), + .cfg_max_payload(cfg_max_payload), + + /* + * Status + */ + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor) +); + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/led_sreg_driver.v b/fpga/lib/pcie/example/fb2CG/fpga/rtl/led_sreg_driver.v new file mode 100644 index 000000000..be970e9b0 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/led_sreg_driver.v @@ -0,0 +1,139 @@ +/* + +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. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * LED shift register driver + */ +module led_sreg_driver #( + // number of LEDs + parameter COUNT = 8, + // invert output + parameter INVERT = 0, + // clock prescale + parameter PRESCALE = 31 +) +( + input wire clk, + input wire rst, + + input wire [COUNT-1:0] led, + + output wire sreg_d, + output wire sreg_ld, + output wire sreg_clk +); + +localparam CL_COUNT = $clog2(COUNT+1); +localparam CL_PRESCALE = $clog2(PRESCALE+1); + +reg [CL_COUNT-1:0] count_reg = 0; +reg [CL_PRESCALE-1:0] prescale_count_reg = 0; +reg enable_reg = 1'b0; +reg update_reg = 1'b1; +reg cycle_reg = 1'b0; + +reg [COUNT-1:0] led_sync_reg_1 = 0; +reg [COUNT-1:0] led_sync_reg_2 = 0; +reg [COUNT-1:0] led_reg = 0; + +reg sreg_d_reg = 1'b0; +reg sreg_ld_reg = 1'b0; +reg sreg_clk_reg = 1'b0; + +assign sreg_d = INVERT ? !sreg_d_reg : sreg_d_reg; +assign sreg_ld = sreg_ld_reg; +assign sreg_clk = sreg_clk_reg; + +always @(posedge clk) begin + led_sync_reg_1 <= led; + led_sync_reg_2 <= led_sync_reg_1; + + enable_reg <= 1'b0; + + if (prescale_count_reg) begin + prescale_count_reg <= prescale_count_reg - 1; + end else begin + enable_reg <= 1'b1; + prescale_count_reg <= PRESCALE; + end + + if (enable_reg) begin + if (cycle_reg) begin + cycle_reg <= 1'b0; + sreg_clk_reg <= 1'b1; + end else if (count_reg) begin + sreg_clk_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + + if (count_reg < COUNT) begin + count_reg <= count_reg + 1; + cycle_reg <= 1'b1; + sreg_d_reg <= led_reg[count_reg]; + end else begin + count_reg <= 0; + cycle_reg <= 1'b0; + sreg_d_reg <= 1'b0; + sreg_ld_reg <= 1'b1; + end + end else begin + sreg_clk_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + + if (update_reg) begin + update_reg <= 1'b0; + + count_reg <= 1; + cycle_reg <= 1'b1; + sreg_d_reg <= led_reg[0]; + end + end + end + + if (led_sync_reg_2 != led_reg) begin + led_reg <= led_sync_reg_2; + update_reg <= 1'b1; + end + + if (rst) begin + count_reg <= 0; + prescale_count_reg <= 0; + enable_reg <= 1'b0; + update_reg <= 1'b1; + cycle_reg <= 1'b0; + led_reg <= 0; + sreg_d_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + sreg_clk_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_reset.v b/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..1fd24d361 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_reset.v @@ -0,0 +1,56 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_signal.v b/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/rtl/sync_signal.v @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014-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 + +`resetall +`timescale 1 ns / 1 ps +`default_nettype none + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/Makefile b/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..7c85b6e54 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/Makefile @@ -0,0 +1,123 @@ +# 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 += ../../rtl/common/example_core_pcie_us.v +VERILOG_SOURCES += ../../rtl/common/example_core_pcie.v +VERILOG_SOURCES += ../../rtl/common/example_core.v +VERILOG_SOURCES += ../../rtl/common/axi_ram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rc.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rq.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cq.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cc.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_RQ_SEQ_NUM_ENABLE ?= 1 +export PARAM_PCIE_TAG_COUNT ?= 64 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_BAR2_APERTURE ?= 24 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE) + COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE) + + 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 diff --git a/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/test_fpga_core.py b/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..94337b028 --- /dev/null +++ b/fpga/lib/pcie/example/fb2CG/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,387 @@ +""" + +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 + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.axi import AxiStreamBus +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"), + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"), + + # Completer reQuest Interface + cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"), + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"), + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(2, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar2 = tb.rc.tree[0][0].bar_addr[2] + + tb.log.info("Test memory write to BAR 2") + + await tb.rc.mem_write(dev_pf0_bar2, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 2") + + val = await tb.rc.mem_read(dev_pf0_bar2, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000118) + tb.log.info("Status: 0x%x", val) + assert val == 0x800000AA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x00020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x000214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x000218) + tb.log.info("Status: 0x%x", val) + assert val == 0x80000055 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "example_core_pcie_us.v"), + os.path.join(rtl_dir, "common", "example_core_pcie.v"), + os.path.join(rtl_dir, "common", "example_core.v"), + os.path.join(rtl_dir, "common", "axi_ram.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_rq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cq.v"), + os.path.join(pcie_rtl_dir, "pcie_us_if_cc.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['RQ_SEQ_NUM_ENABLE'] = 1 + parameters['PCIE_TAG_COUNT'] = 64 + parameters['BAR0_APERTURE'] = 24 + parameters['BAR2_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/lib/pcie/example/fb2CG/fpga_axi/ip/pcie4_uscale_plus_0.tcl b/fpga/lib/pcie/example/fb2CG/fpga_axi/ip/pcie4_uscale_plus_0.tcl index 8a0e0451b..75f0eddca 100644 --- a/fpga/lib/pcie/example/fb2CG/fpga_axi/ip/pcie4_uscale_plus_0.tcl +++ b/fpga/lib/pcie/example/fb2CG/fpga_axi/ip/pcie4_uscale_plus_0.tcl @@ -8,15 +8,11 @@ set_property -dict [list \ CONFIG.axisten_if_enable_client_tag {true} \ CONFIG.axisten_if_width {512_bit} \ CONFIG.axisten_freq {250} \ - CONFIG.PF0_CLASS_CODE {020000} \ + CONFIG.PF0_CLASS_CODE {058000} \ CONFIG.PF0_DEVICE_ID {0001} \ CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \ - CONFIG.PF0_SUBSYSTEM_ID {0001} \ - CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \ - CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \ - CONFIG.pf0_class_code_sub {00} \ - CONFIG.pf0_base_class_menu {Network_controller} \ - CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \ + CONFIG.PF0_SUBSYSTEM_ID {a00e} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1c2c} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_prefetchable {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ diff --git a/fpga/lib/pcie/rtl/dma_client_axis_sink.v b/fpga/lib/pcie/rtl/dma_client_axis_sink.v index c2d322686..5f5956c80 100644 --- a/fpga/lib/pcie/rtl/dma_client_axis_sink.v +++ b/fpga/lib/pcie/rtl/dma_client_axis_sink.v @@ -570,11 +570,11 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_BE_WIDTH-1:0] out_fifo_wr_cmd_be[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_ADDR_WIDTH-1:0] out_fifo_wr_cmd_addr[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_DATA_WIDTH-1:0] out_fifo_wr_cmd_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] done_count_reg = 0; diff --git a/fpga/lib/pcie/rtl/dma_client_axis_source.v b/fpga/lib/pcie/rtl/dma_client_axis_source.v index bae229e06..4ed5777af 100644 --- a/fpga/lib/pcie/rtl/dma_client_axis_source.v +++ b/fpga/lib/pcie/rtl/dma_client_axis_source.v @@ -507,17 +507,17 @@ reg out_fifo_half_full_reg = 1'b0; wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXIS_DATA_WIDTH-1:0] out_fifo_tdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXIS_KEEP_WIDTH-1:0] out_fifo_tkeep[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg out_fifo_tlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXIS_ID_WIDTH-1:0] out_fifo_tid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXIS_DEST_WIDTH-1:0] out_fifo_tdest[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXIS_USER_WIDTH-1:0] out_fifo_tuser[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; assign m_axis_read_data_tready_int = !out_fifo_half_full_reg; diff --git a/fpga/lib/pcie/rtl/dma_if_axi_rd.v b/fpga/lib/pcie/rtl/dma_if_axi_rd.v index 7d17cd677..1a0065856 100644 --- a/fpga/lib/pcie/rtl/dma_if_axi_rd.v +++ b/fpga/lib/pcie/rtl/dma_if_axi_rd.v @@ -241,8 +241,11 @@ reg [OP_TAG_WIDTH-1:0] op_tag_reg = {OP_TAG_WIDTH{1'b0}}, op_tag_next; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_wr_ptr_reg = 0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_rd_ptr_reg = 0, status_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] status_fifo_op_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_COUNT-1:0] status_fifo_mask[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg status_fifo_finish[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; reg [OP_TAG_WIDTH-1:0] status_fifo_wr_op_tag; reg [RAM_SEG_COUNT-1:0] status_fifo_wr_mask; @@ -315,13 +318,21 @@ reg [OP_TAG_WIDTH+1-1:0] op_table_finish_ptr_reg = 0; reg op_table_finish_en; reg [2**OP_TAG_WIDTH-1:0] op_table_active = 0; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_ADDR_WIDTH-1:0] op_table_axi_addr [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEL_WIDTH-1:0] op_table_ram_sel [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_ADDR_WIDTH-1:0] op_table_ram_addr [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_last[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_write_complete[2**OP_TAG_WIDTH-1:0]; integer i; @@ -789,13 +800,13 @@ for (n = 0; n < RAM_SEG_COUNT; n = n + 1) begin wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEL_WIDTH-1:0] out_fifo_wr_cmd_sel[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_BE_WIDTH-1:0] out_fifo_wr_cmd_be[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_ADDR_WIDTH-1:0] out_fifo_wr_cmd_addr[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_DATA_WIDTH-1:0] out_fifo_wr_cmd_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] done_count_reg = 0; diff --git a/fpga/lib/pcie/rtl/dma_if_axi_wr.v b/fpga/lib/pcie/rtl/dma_if_axi_wr.v index 15534ba55..a9d191be1 100644 --- a/fpga/lib/pcie/rtl/dma_if_axi_wr.v +++ b/fpga/lib/pcie/rtl/dma_if_axi_wr.v @@ -273,6 +273,7 @@ reg read_cmd_valid_reg = 1'b0, read_cmd_valid_next; reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_wr_ptr_reg = 0; reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_rd_ptr_reg = 0, mask_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_COUNT-1:0] mask_fifo_mask[(2**MASK_FIFO_ADDR_WIDTH)-1:0]; reg [RAM_SEG_COUNT-1:0] mask_fifo_wr_mask; @@ -345,11 +346,17 @@ reg op_table_finish_en; reg [2**OP_TAG_WIDTH-1:0] op_table_active = 0; reg [2**OP_TAG_WIDTH-1:0] op_table_write_complete = 0; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_ADDR_WIDTH-1:0] op_table_axi_addr[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_last[2**OP_TAG_WIDTH-1:0]; integer i; @@ -926,11 +933,11 @@ reg out_fifo_half_full_reg = 1'b0; wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_DATA_WIDTH-1:0] out_fifo_wdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_STRB_WIDTH-1:0] out_fifo_wstrb[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg out_fifo_wlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; assign m_axi_wready_int = !out_fifo_half_full_reg; diff --git a/fpga/lib/pcie/rtl/dma_if_pcie_rd.v b/fpga/lib/pcie/rtl/dma_if_pcie_rd.v index aaf1e00ea..680e5af91 100644 --- a/fpga/lib/pcie/rtl/dma_if_pcie_rd.v +++ b/fpga/lib/pcie/rtl/dma_if_pcie_rd.v @@ -324,6 +324,7 @@ reg [LEN_WIDTH-1:0] req_op_count_reg = {LEN_WIDTH{1'b0}}, req_op_count_next; reg [12:0] req_tlp_count_reg = 13'd0, req_tlp_count_next; reg req_zero_len_reg = 1'b0, req_zero_len_next; reg [OP_TAG_WIDTH-1:0] req_op_tag_reg = {OP_TAG_WIDTH{1'b0}}, req_op_tag_next; +reg req_op_tag_valid_reg = 1'b0, req_op_tag_valid_next; reg [PCIE_TAG_WIDTH-1:0] req_pcie_tag_reg = {PCIE_TAG_WIDTH{1'b0}}, req_pcie_tag_next; reg req_pcie_tag_valid_reg = 1'b0, req_pcie_tag_valid_next; @@ -377,9 +378,13 @@ reg have_credit_reg = 1'b0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_wr_ptr_reg = 0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_rd_ptr_reg = 0, status_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] status_fifo_op_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_COUNT-1:0] status_fifo_mask[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg status_fifo_finish[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] status_fifo_error[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; reg [OP_TAG_WIDTH-1:0] status_fifo_wr_op_tag; reg [RAM_SEG_COUNT-1:0] status_fifo_wr_mask; @@ -491,22 +496,30 @@ reg pcie_tag_table_start_en_reg = 1'b0, pcie_tag_table_start_en_next; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_table_finish_ptr; reg pcie_tag_table_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEL_WIDTH-1:0] pcie_tag_table_ram_sel[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_ADDR_WIDTH-1:0] pcie_tag_table_ram_addr[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] pcie_tag_table_op_tag[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_zero_len[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_a[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_b[(2**PCIE_TAG_WIDTH)-1:0]; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_wr_tag; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_rd_ptr_reg = 0, pcie_tag_fifo_1_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH_1-1:0] pcie_tag_fifo_1_mem [2**PCIE_TAG_WIDTH_1-1:0]; reg pcie_tag_fifo_1_we; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_rd_ptr_reg = 0, pcie_tag_fifo_2_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_2_mem [2**PCIE_TAG_WIDTH_2-1:0]; reg pcie_tag_fifo_2_we; @@ -523,18 +536,28 @@ reg op_table_update_status_en; reg [OP_TAG_WIDTH-1:0] op_table_read_finish_ptr; reg op_table_read_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_commit [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_start [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_finish [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] op_table_error_code [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_wr_ptr_reg = 0; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_rd_ptr_reg = 0, op_tag_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] op_tag_fifo_mem [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH-1:0] op_tag_fifo_wr_tag; reg op_tag_fifo_we; @@ -588,12 +611,13 @@ always @* begin req_tlp_count_next = req_tlp_count_reg; req_zero_len_next = req_zero_len_reg; req_op_tag_next = req_op_tag_reg; + req_op_tag_valid_next = req_op_tag_valid_reg; req_pcie_tag_next = req_pcie_tag_reg; req_pcie_tag_valid_next = req_pcie_tag_valid_reg; inc_active_tx = 1'b0; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b0; @@ -601,8 +625,6 @@ always @* begin op_table_read_start_commit = 1'b0; op_table_read_start_en = 1'b0; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; - // TLP size computation if (req_op_count_reg + req_pcie_addr_reg[1:0] <= {max_read_request_size_dw_reg, 2'b00}) begin // packet smaller than max read request size @@ -696,7 +718,7 @@ always @* begin // TLP segmentation and request generation case (req_state_reg) REQ_STATE_IDLE: begin - s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); + s_axis_read_desc_ready_next = init_done_reg && enable && req_op_tag_valid_reg; if (s_axis_read_desc_ready && s_axis_read_desc_valid) begin s_axis_read_desc_ready_next = 1'b0; @@ -711,12 +733,10 @@ always @* begin req_op_count_next = s_axis_read_desc_len; req_zero_len_next = 1'b0; end - req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b1; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg+1; - stat_rd_op_start_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + stat_rd_op_start_tag_next = req_op_tag_reg; stat_rd_op_start_len_next = s_axis_read_desc_len; stat_rd_op_start_valid_next = 1'b1; req_state_next = REQ_STATE_START; @@ -758,6 +778,7 @@ always @* begin if (!req_last_tlp) begin req_state_next = REQ_STATE_START; end else begin + req_op_tag_valid_next = 1'b0; s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); req_state_next = REQ_STATE_IDLE; end @@ -767,6 +788,16 @@ always @* begin end endcase + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; + + if (!req_op_tag_valid_next) begin + if (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg) begin + req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + req_op_tag_valid_next = 1'b1; + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg + 1; + end + end + pcie_tag_fifo_1_rd_ptr_next = pcie_tag_fifo_1_rd_ptr_reg; pcie_tag_fifo_2_rd_ptr_next = pcie_tag_fifo_2_rd_ptr_reg; @@ -1299,6 +1330,7 @@ always @(posedge clk) begin req_tlp_count_reg <= req_tlp_count_next; req_zero_len_reg <= req_zero_len_next; req_op_tag_reg <= req_op_tag_next; + req_op_tag_valid_reg <= req_op_tag_valid_next; req_pcie_tag_reg <= req_pcie_tag_next; req_pcie_tag_valid_reg <= req_pcie_tag_valid_next; @@ -1474,6 +1506,7 @@ always @(posedge clk) begin init_pcie_tag_reg <= 1'b1; init_op_tag_reg <= 1'b1; + req_op_tag_valid_reg <= 1'b0; req_pcie_tag_valid_reg <= 1'b0; finish_tag_reg <= 1'b0; @@ -1542,13 +1575,13 @@ for (n = 0; n < RAM_SEG_COUNT; n = n + 1) begin wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEL_WIDTH-1:0] out_fifo_wr_cmd_sel[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_BE_WIDTH-1:0] out_fifo_wr_cmd_be[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_ADDR_WIDTH-1:0] out_fifo_wr_cmd_addr[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_DATA_WIDTH-1:0] out_fifo_wr_cmd_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] done_count_reg = 0; diff --git a/fpga/lib/pcie/rtl/dma_if_pcie_us_rd.v b/fpga/lib/pcie/rtl/dma_if_pcie_us_rd.v index 8e3f50ee3..5f9aeb3de 100644 --- a/fpga/lib/pcie/rtl/dma_if_pcie_us_rd.v +++ b/fpga/lib/pcie/rtl/dma_if_pcie_us_rd.v @@ -352,6 +352,7 @@ reg [LEN_WIDTH-1:0] req_op_count_reg = {LEN_WIDTH{1'b0}}, req_op_count_next; reg [12:0] req_tlp_count_reg = 13'd0, req_tlp_count_next; reg req_zero_len_reg = 1'b0, req_zero_len_next; reg [OP_TAG_WIDTH-1:0] req_op_tag_reg = {OP_TAG_WIDTH{1'b0}}, req_op_tag_next; +reg req_op_tag_valid_reg = 1'b0, req_op_tag_valid_next; reg [PCIE_TAG_WIDTH-1:0] req_pcie_tag_reg = {PCIE_TAG_WIDTH{1'b0}}, req_pcie_tag_next; reg req_pcie_tag_valid_reg = 1'b0, req_pcie_tag_valid_next; @@ -391,9 +392,13 @@ reg have_credit_reg = 1'b0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_wr_ptr_reg = 0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_rd_ptr_reg = 0, status_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] status_fifo_op_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_COUNT-1:0] status_fifo_mask[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg status_fifo_finish[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] status_fifo_error[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; reg [OP_TAG_WIDTH-1:0] status_fifo_wr_op_tag; reg [SEG_COUNT-1:0] status_fifo_wr_mask; @@ -464,22 +469,30 @@ reg pcie_tag_table_start_en_reg = 1'b0, pcie_tag_table_start_en_next; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_table_finish_ptr; reg pcie_tag_table_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEL_WIDTH-1:0] pcie_tag_table_ram_sel[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_ADDR_WIDTH-1:0] pcie_tag_table_ram_addr[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] pcie_tag_table_op_tag[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_zero_len[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_a[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_b[(2**PCIE_TAG_WIDTH)-1:0]; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_wr_tag; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_rd_ptr_reg = 0, pcie_tag_fifo_1_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH_1-1:0] pcie_tag_fifo_1_mem [2**PCIE_TAG_WIDTH_1-1:0]; reg pcie_tag_fifo_1_we; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_rd_ptr_reg = 0, pcie_tag_fifo_2_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_2_mem [2**PCIE_TAG_WIDTH_2-1:0]; reg pcie_tag_fifo_2_we; @@ -496,18 +509,28 @@ reg op_table_update_status_en; reg [OP_TAG_WIDTH-1:0] op_table_read_finish_ptr; reg op_table_read_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_commit [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_start [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_finish [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] op_table_error_code [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_wr_ptr_reg = 0; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_rd_ptr_reg = 0, op_tag_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] op_tag_fifo_mem [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH-1:0] op_tag_fifo_wr_tag; reg op_tag_fifo_we; @@ -549,12 +572,13 @@ always @* begin req_tlp_count_next = req_tlp_count_reg; req_zero_len_next = req_zero_len_reg; req_op_tag_next = req_op_tag_reg; + req_op_tag_valid_next = req_op_tag_valid_reg; req_pcie_tag_next = req_pcie_tag_reg; req_pcie_tag_valid_next = req_pcie_tag_valid_reg; inc_active_tx = 1'b0; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b0; @@ -562,8 +586,6 @@ always @* begin op_table_read_start_commit = 1'b0; op_table_read_start_en = 1'b0; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; - // TLP size computation if (req_op_count_reg + req_pcie_addr_reg[1:0] <= {max_read_request_size_dw_reg, 2'b00}) begin // packet smaller than max read request size @@ -688,7 +710,7 @@ always @* begin // TLP segmentation and request generation case (req_state_reg) REQ_STATE_IDLE: begin - s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); + s_axis_read_desc_ready_next = init_done_reg && enable && req_op_tag_valid_reg; if (s_axis_read_desc_ready && s_axis_read_desc_valid) begin s_axis_read_desc_ready_next = 1'b0; @@ -703,11 +725,9 @@ always @* begin req_op_count_next = s_axis_read_desc_len; req_zero_len_next = 1'b0; end - req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b1; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg+1; req_state_next = REQ_STATE_START; end else begin req_state_next = REQ_STATE_IDLE; @@ -740,6 +760,7 @@ always @* begin if (!req_last_tlp) begin req_state_next = REQ_STATE_START; end else begin + req_op_tag_valid_next = 1'b0; s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); req_state_next = REQ_STATE_IDLE; end @@ -779,6 +800,7 @@ always @* begin if (!req_last_tlp) begin req_state_next = REQ_STATE_START; end else begin + req_op_tag_valid_next = 1'b0; s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); req_state_next = REQ_STATE_IDLE; end @@ -789,6 +811,16 @@ always @* begin end endcase + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; + + if (!req_op_tag_valid_next) begin + if (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg) begin + req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + req_op_tag_valid_next = 1'b1; + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg + 1; + end + end + pcie_tag_fifo_1_rd_ptr_next = pcie_tag_fifo_1_rd_ptr_reg; pcie_tag_fifo_2_rd_ptr_next = pcie_tag_fifo_2_rd_ptr_reg; @@ -1457,6 +1489,7 @@ always @(posedge clk) begin req_tlp_count_reg <= req_tlp_count_next; req_zero_len_reg <= req_zero_len_next; req_op_tag_reg <= req_op_tag_next; + req_op_tag_valid_reg <= req_op_tag_valid_next; req_pcie_tag_reg <= req_pcie_tag_next; req_pcie_tag_valid_reg <= req_pcie_tag_valid_next; @@ -1622,6 +1655,7 @@ always @(posedge clk) begin init_pcie_tag_reg <= 1'b1; init_op_tag_reg <= 1'b1; + req_op_tag_valid_reg <= 1'b0; req_pcie_tag_valid_reg <= 1'b0; finish_tag_reg <= 1'b0; diff --git a/fpga/lib/pcie/rtl/dma_if_pcie_us_wr.v b/fpga/lib/pcie/rtl/dma_if_pcie_us_wr.v index 813943cf7..7974d6599 100644 --- a/fpga/lib/pcie/rtl/dma_if_pcie_us_wr.v +++ b/fpga/lib/pcie/rtl/dma_if_pcie_us_wr.v @@ -354,6 +354,7 @@ reg [RQ_SEQ_NUM_WIDTH-1:0] tlp_seq_num_reg = {RQ_SEQ_NUM_WIDTH{1'b0}}, tlp_seq_n reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_wr_ptr_reg = 0; reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_rd_ptr_reg = 0, mask_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_COUNT-1:0] mask_fifo_mask[(2**MASK_FIFO_ADDR_WIDTH)-1:0]; reg [SEG_COUNT-1:0] mask_fifo_wr_mask; @@ -429,13 +430,21 @@ reg op_table_finish_en; reg [2**OP_TAG_WIDTH-1:0] op_table_active = 0; reg [2**OP_TAG_WIDTH-1:0] op_table_tx_done = 0; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_ADDR_WIDTH-1:0] op_table_pcie_addr[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_zero_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [9:0] op_table_dword_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_last[2**OP_TAG_WIDTH-1:0]; integer i; diff --git a/fpga/lib/pcie/rtl/dma_if_pcie_wr.v b/fpga/lib/pcie/rtl/dma_if_pcie_wr.v index 0846ff7a0..03d2f3676 100644 --- a/fpga/lib/pcie/rtl/dma_if_pcie_wr.v +++ b/fpga/lib/pcie/rtl/dma_if_pcie_wr.v @@ -308,6 +308,7 @@ reg [127:0] tlp_hdr; reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_wr_ptr_reg = 0; reg [MASK_FIFO_ADDR_WIDTH+1-1:0] mask_fifo_rd_ptr_reg = 0, mask_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_SEG_COUNT-1:0] mask_fifo_mask[(2**MASK_FIFO_ADDR_WIDTH)-1:0]; reg [RAM_SEG_COUNT-1:0] mask_fifo_wr_mask; @@ -411,13 +412,21 @@ reg op_table_finish_en; reg [2**OP_TAG_WIDTH-1:0] op_table_active = 0; reg [2**OP_TAG_WIDTH-1:0] op_table_tx_done = 0; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_ADDR_WIDTH-1:0] op_table_pcie_addr[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_zero_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [9:0] op_table_dword_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [RAM_OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_last[2**OP_TAG_WIDTH-1:0]; integer i; diff --git a/fpga/lib/pcie/rtl/dma_psdpram.v b/fpga/lib/pcie/rtl/dma_psdpram.v index c66cbc513..a0f2283af 100644 --- a/fpga/lib/pcie/rtl/dma_psdpram.v +++ b/fpga/lib/pcie/rtl/dma_psdpram.v @@ -87,6 +87,7 @@ generate for (n = 0; n < SEG_COUNT; n = n + 1) begin + (* ramstyle = "no_rw_check" *) reg [SEG_DATA_WIDTH-1:0] mem_reg[2**INT_ADDR_WIDTH-1:0]; reg wr_done_reg = 1'b0; diff --git a/fpga/lib/pcie/rtl/dma_psdpram_async.v b/fpga/lib/pcie/rtl/dma_psdpram_async.v index 61895304b..f67c7416c 100644 --- a/fpga/lib/pcie/rtl/dma_psdpram_async.v +++ b/fpga/lib/pcie/rtl/dma_psdpram_async.v @@ -88,6 +88,7 @@ generate for (n = 0; n < SEG_COUNT; n = n + 1) begin + (* ramstyle = "no_rw_check" *) reg [SEG_DATA_WIDTH-1:0] mem_reg[2**INT_ADDR_WIDTH-1:0]; reg wr_done_reg = 1'b0; diff --git a/fpga/lib/pcie/rtl/dma_ram_demux_rd.v b/fpga/lib/pcie/rtl/dma_ram_demux_rd.v index b97472744..a4ee6202c 100644 --- a/fpga/lib/pcie/rtl/dma_ram_demux_rd.v +++ b/fpga/lib/pcie/rtl/dma_ram_demux_rd.v @@ -98,6 +98,7 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin // FIFO to maintain response ordering reg [FIFO_ADDR_WIDTH+1-1:0] fifo_wr_ptr_reg = 0; reg [FIFO_ADDR_WIDTH+1-1:0] fifo_rd_ptr_reg = 0; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CL_PORTS-1:0] fifo_sel[(2**FIFO_ADDR_WIDTH)-1:0]; wire fifo_empty = fifo_wr_ptr_reg == fifo_rd_ptr_reg; @@ -295,7 +296,7 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; - (* ram_style = "distributed" *) + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [SEG_DATA_WIDTH-1:0] out_fifo_rd_resp_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; assign seg_ctrl_rd_resp_ready_int = !out_fifo_half_full_reg; diff --git a/fpga/lib/pcie/rtl/dma_ram_demux_wr.v b/fpga/lib/pcie/rtl/dma_ram_demux_wr.v index a0c65f67e..a40c28a9a 100644 --- a/fpga/lib/pcie/rtl/dma_ram_demux_wr.v +++ b/fpga/lib/pcie/rtl/dma_ram_demux_wr.v @@ -99,6 +99,7 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin // FIFO to maintain response ordering reg [FIFO_ADDR_WIDTH+1-1:0] fifo_wr_ptr_reg = 0; reg [FIFO_ADDR_WIDTH+1-1:0] fifo_rd_ptr_reg = 0; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CL_PORTS-1:0] fifo_sel[(2**FIFO_ADDR_WIDTH)-1:0]; wire fifo_empty = fifo_wr_ptr_reg == fifo_rd_ptr_reg; diff --git a/fpga/lib/pcie/rtl/pcie_axi_master_wr.v b/fpga/lib/pcie/rtl/pcie_axi_master_wr.v index b2d69f134..99ebb1e71 100644 --- a/fpga/lib/pcie/rtl/pcie_axi_master_wr.v +++ b/fpga/lib/pcie/rtl/pcie_axi_master_wr.v @@ -498,11 +498,11 @@ reg out_fifo_half_full_reg = 1'b0; wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_DATA_WIDTH-1:0] out_fifo_wdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_STRB_WIDTH-1:0] out_fifo_wstrb[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; -(* ram_style = "distributed" *) +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg out_fifo_wlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; assign m_axi_wready_int = !out_fifo_half_full_reg; diff --git a/fpga/lib/pcie/rtl/pcie_axil_master.v b/fpga/lib/pcie/rtl/pcie_axil_master.v index 656ba2a09..d7d172c98 100644 --- a/fpga/lib/pcie/rtl/pcie_axil_master.v +++ b/fpga/lib/pcie/rtl/pcie_axil_master.v @@ -220,17 +220,29 @@ reg [127:0] cpl_tlp_hdr; reg [RESP_FIFO_ADDR_WIDTH+1-1:0] resp_fifo_wr_ptr_reg = 0; reg [RESP_FIFO_ADDR_WIDTH+1-1:0] resp_fifo_rd_ptr_reg = 0, resp_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_op_read[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_op_write[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_first[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_last[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_cpl_status[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [5:0] resp_fifo_dword_count[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] resp_fifo_byte_count[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [6:0] resp_fifo_lower_addr[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [15:0] resp_fifo_requester_id[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [9:0] resp_fifo_tag[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_tc[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_attr[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; reg resp_fifo_wr_op_read; diff --git a/fpga/lib/pcie/rtl/pcie_axil_master_minimal.v b/fpga/lib/pcie/rtl/pcie_axil_master_minimal.v index 27a2b153b..acbfd037d 100644 --- a/fpga/lib/pcie/rtl/pcie_axil_master_minimal.v +++ b/fpga/lib/pcie/rtl/pcie_axil_master_minimal.v @@ -194,14 +194,23 @@ reg [127:0] cpl_tlp_hdr; reg [RESP_FIFO_ADDR_WIDTH+1-1:0] resp_fifo_wr_ptr_reg = 0; reg [RESP_FIFO_ADDR_WIDTH+1-1:0] resp_fifo_rd_ptr_reg = 0, resp_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_op_read[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg resp_fifo_op_write[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_cpl_status[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_byte_count[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [6:0] resp_fifo_lower_addr[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [15:0] resp_fifo_requester_id[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [9:0] resp_fifo_tag[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_tc[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [2:0] resp_fifo_attr[(2**RESP_FIFO_ADDR_WIDTH)-1:0]; reg resp_fifo_wr_op_read; diff --git a/fpga/lib/pcie/rtl/pcie_s10_cfg.v b/fpga/lib/pcie/rtl/pcie_s10_cfg.v new file mode 100644 index 000000000..4156cd85b --- /dev/null +++ b/fpga/lib/pcie/rtl/pcie_s10_cfg.v @@ -0,0 +1,305 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Intel Stratix 10 H-Tile/L-Tile PCIe configuration interface + */ +module pcie_s10_cfg # +( + // Tile selection (0 for H-Tile, 1 for L-Tile) + parameter L_TILE = 0, + // Number of physical functions + parameter PF_COUNT = 1 +) +( + input wire clk, + input wire rst, + + /* + * Configuration input from H-Tile/L-Tile + */ + input wire [31:0] tl_cfg_ctl, + input wire [4:0] tl_cfg_add, + input wire [1:0] tl_cfg_func, + + /* + * Configuration output + */ + output reg [PF_COUNT-1:0] cfg_memory_space_en, + output reg [PF_COUNT-1:0] cfg_ido_cpl_en, + output reg [PF_COUNT-1:0] cfg_perr_en, + output reg [PF_COUNT-1:0] cfg_serr_en, + output reg [PF_COUNT-1:0] cfg_fatal_err_rpt_en, + output reg [PF_COUNT-1:0] cfg_nonfatal_err_rpt_en, + output reg [PF_COUNT-1:0] cfg_corr_err_rpt_en, + output reg [PF_COUNT-1:0] cfg_unsupported_req_rpt_en, + output reg [PF_COUNT-1:0] cfg_bus_master_en, + output reg [PF_COUNT-1:0] cfg_ext_tag_en, + output reg [PF_COUNT*3-1:0] cfg_max_read_request_size, + output reg [PF_COUNT*3-1:0] cfg_max_payload_size, + output reg [PF_COUNT-1:0] cfg_ido_request_en, + output reg [PF_COUNT-1:0] cfg_no_snoop_en, + output reg [PF_COUNT-1:0] cfg_relaxed_ordering_en, + output reg [PF_COUNT*5-1:0] cfg_device_num, + output reg [PF_COUNT*8-1:0] cfg_bus_num, + output reg [PF_COUNT-1:0] cfg_pm_no_soft_rst, + output reg [PF_COUNT-1:0] cfg_rcb_ctrl, + output reg [PF_COUNT-1:0] cfg_irq_disable, + output reg [PF_COUNT*5-1:0] cfg_pcie_cap_irq_msg_num, + output reg [PF_COUNT-1:0] cfg_sys_pwr_ctrl, + output reg [PF_COUNT*2-1:0] cfg_sys_atten_ind_ctrl, + output reg [PF_COUNT*2-1:0] cfg_sys_pwr_ind_ctrl, + output reg [PF_COUNT*16-1:0] cfg_num_vf, + output reg [PF_COUNT*5-1:0] cfg_ats_stu, + output reg [PF_COUNT-1:0] cfg_ats_cache_en, + output reg [PF_COUNT-1:0] cfg_ari_forward_en, + output reg [PF_COUNT-1:0] cfg_atomic_request_en, + output reg [PF_COUNT*3-1:0] cfg_tph_st_mode, + output reg [PF_COUNT*2-1:0] cfg_tph_en, + output reg [PF_COUNT-1:0] cfg_vf_en, + output reg [PF_COUNT*4-1:0] cfg_an_link_speed, + output reg [PF_COUNT*6-1:0] cfg_an_link_width, + output reg [PF_COUNT*11-1:0] cfg_start_vf_index, + output reg [PF_COUNT*64-1:0] cfg_msi_address, + output reg [PF_COUNT*32-1:0] cfg_msi_mask, + output reg [PF_COUNT-1:0] cfg_send_f_err, + output reg [PF_COUNT-1:0] cfg_send_nf_err, + output reg [PF_COUNT-1:0] cfg_send_cor_err, + output reg [PF_COUNT*5-1:0] cfg_aer_irq_msg_num, + output reg [PF_COUNT-1:0] cfg_msix_func_mask, + output reg [PF_COUNT-1:0] cfg_msix_enable, + output reg [PF_COUNT*3-1:0] cfg_multiple_msi_enable, + output reg [PF_COUNT-1:0] cfg_64bit_msi, + output reg [PF_COUNT-1:0] cfg_msi_enable, + output reg [PF_COUNT*16-1:0] cfg_msi_data, + output reg [PF_COUNT*32-1:0] cfg_aer_uncor_err_mask, + output reg [PF_COUNT*32-1:0] cfg_aer_corr_err_mask, + output reg [PF_COUNT*32-1:0] cfg_aer_uncor_err_severity +); + +always @(posedge clk) begin + if (tl_cfg_func < PF_COUNT) begin + if (L_TILE) begin + case (tl_cfg_add[3:0]) + 4'h0: begin + cfg_ido_request_en[tl_cfg_func +: 1] <= tl_cfg_ctl[31]; + cfg_no_snoop_en[tl_cfg_func +: 1] <= tl_cfg_ctl[30]; + cfg_relaxed_ordering_en[tl_cfg_func +: 1] <= tl_cfg_ctl[29]; + cfg_device_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[28:24]; + cfg_bus_num[tl_cfg_func*8 +: 8] <= tl_cfg_ctl[23:16]; + cfg_memory_space_en[tl_cfg_func +: 1] <= tl_cfg_ctl[15]; + cfg_ido_cpl_en[tl_cfg_func +: 1] <= tl_cfg_ctl[14]; + cfg_an_link_width[tl_cfg_func*6 +: 6] <= tl_cfg_ctl[13:8]; + cfg_bus_master_en[tl_cfg_func +: 1] <= tl_cfg_ctl[7]; + cfg_ext_tag_en[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_max_read_request_size[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[5:3]; + cfg_max_payload_size[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[2:0]; + end + 4'h1: begin + cfg_send_f_err[tl_cfg_func +: 1] <= tl_cfg_ctl[31]; + cfg_send_nf_err[tl_cfg_func +: 1] <= tl_cfg_ctl[30]; + cfg_send_cor_err[tl_cfg_func +: 1] <= tl_cfg_ctl[29]; + cfg_aer_irq_msg_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[28:24]; + cfg_an_link_width[tl_cfg_func*6 +: 6] <= tl_cfg_ctl[23:18]; + cfg_pm_no_soft_rst[tl_cfg_func +: 1] <= tl_cfg_ctl[17]; + cfg_rcb_ctrl[tl_cfg_func +: 1] <= tl_cfg_ctl[16]; + cfg_irq_disable[tl_cfg_func +: 1] <= tl_cfg_ctl[13]; + cfg_pcie_cap_irq_msg_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[12:8]; + cfg_sys_pwr_ctrl[tl_cfg_func +: 1] <= tl_cfg_ctl[4]; + cfg_sys_atten_ind_ctrl[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[3:2]; + cfg_sys_pwr_ind_ctrl[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[1:0]; + end + 4'h2: begin + cfg_start_vf_index[tl_cfg_func*11 +: 11] <= tl_cfg_ctl[31:24]; + cfg_num_vf[tl_cfg_func*16 +: 16] <= tl_cfg_ctl[23:16]; + cfg_an_link_speed[tl_cfg_func*4 +: 4] <= tl_cfg_ctl[15:12]; + cfg_ats_stu[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[11:7]; + cfg_ats_cache_en[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_ari_forward_en[tl_cfg_func +: 1] <= tl_cfg_ctl[5]; + cfg_atomic_request_en[tl_cfg_func +: 1] <= tl_cfg_ctl[4]; + cfg_tph_st_mode[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[3:2]; + cfg_tph_en[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[1]; + cfg_vf_en[tl_cfg_func +: 1] <= tl_cfg_ctl[0]; + end + 4'h3: begin + cfg_msi_address[tl_cfg_func*64+0 +: 32] <= tl_cfg_ctl; + end + 4'h4: begin + cfg_msi_address[tl_cfg_func*64+32 +: 32] <= tl_cfg_ctl; + end + 4'h5: begin + cfg_msi_mask[tl_cfg_func*32 +: 32] <= tl_cfg_ctl; + end + 4'h6: begin + cfg_msi_data[tl_cfg_func*16 +: 16] <= tl_cfg_ctl[31:16]; + cfg_msix_func_mask[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_msix_enable[tl_cfg_func +: 1] <= tl_cfg_ctl[5]; + cfg_multiple_msi_enable[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[4:2]; + cfg_64bit_msi[tl_cfg_func +: 1] <= tl_cfg_ctl[1]; + cfg_msi_enable[tl_cfg_func +: 1] <= tl_cfg_ctl[0]; + end + 4'h7: begin + cfg_an_link_speed[tl_cfg_func*4 +: 4] <= tl_cfg_ctl[9:6]; + cfg_an_link_width[tl_cfg_func*6 +: 6] <= tl_cfg_ctl[5:0]; + end + endcase + end else begin + case (tl_cfg_add) + 5'h00: begin + cfg_ido_request_en[tl_cfg_func +: 1] <= tl_cfg_ctl[31]; + cfg_no_snoop_en[tl_cfg_func +: 1] <= tl_cfg_ctl[30]; + cfg_relaxed_ordering_en[tl_cfg_func +: 1] <= tl_cfg_ctl[29]; + cfg_device_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[28:24]; + cfg_bus_num[tl_cfg_func*8 +: 8] <= tl_cfg_ctl[23:16]; + cfg_memory_space_en[tl_cfg_func +: 1] <= tl_cfg_ctl[15]; + cfg_ido_cpl_en[tl_cfg_func +: 1] <= tl_cfg_ctl[14]; + cfg_perr_en[tl_cfg_func +: 1] <= tl_cfg_ctl[13]; + cfg_serr_en[tl_cfg_func +: 1] <= tl_cfg_ctl[12]; + cfg_fatal_err_rpt_en[tl_cfg_func +: 1] <= tl_cfg_ctl[11]; + cfg_nonfatal_err_rpt_en[tl_cfg_func +: 1] <= tl_cfg_ctl[10]; + cfg_corr_err_rpt_en[tl_cfg_func +: 1] <= tl_cfg_ctl[9]; + cfg_unsupported_req_rpt_en[tl_cfg_func +: 1] <= tl_cfg_ctl[8]; + cfg_bus_master_en[tl_cfg_func +: 1] <= tl_cfg_ctl[7]; + cfg_ext_tag_en[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_max_read_request_size[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[5:3]; + cfg_max_payload_size[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[2:0]; + end + 5'h01: begin + cfg_num_vf[tl_cfg_func*16 +: 16] <= tl_cfg_ctl[31:16]; + cfg_pm_no_soft_rst[tl_cfg_func +: 1] <= tl_cfg_ctl[15]; + cfg_rcb_ctrl[tl_cfg_func +: 1] <= tl_cfg_ctl[14]; + cfg_irq_disable[tl_cfg_func +: 1] <= tl_cfg_ctl[13]; + cfg_pcie_cap_irq_msg_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[12:8]; + cfg_sys_pwr_ctrl[tl_cfg_func +: 1] <= tl_cfg_ctl[4]; + cfg_sys_atten_ind_ctrl[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[3:2]; + cfg_sys_pwr_ind_ctrl[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[1:0]; + end + 5'h02: begin + cfg_an_link_speed[tl_cfg_func*4 +: 4] <= tl_cfg_ctl[31:28]; + cfg_start_vf_index[tl_cfg_func*11 +: 11] <= tl_cfg_ctl[27:17]; + cfg_ats_stu[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[13:9]; + cfg_ats_cache_en[tl_cfg_func +: 1] <= tl_cfg_ctl[8]; + cfg_ari_forward_en[tl_cfg_func +: 1] <= tl_cfg_ctl[7]; + cfg_atomic_request_en[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_tph_st_mode[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[5:3]; + cfg_tph_en[tl_cfg_func*2 +: 2] <= tl_cfg_ctl[2:1]; + cfg_vf_en[tl_cfg_func +: 1] <= tl_cfg_ctl[0]; + end + 5'h03: begin + cfg_msi_address[tl_cfg_func*64+0 +: 32] <= tl_cfg_ctl; + end + 5'h04: begin + cfg_msi_address[tl_cfg_func*64+32 +: 32] <= tl_cfg_ctl; + end + 5'h05: begin + cfg_msi_mask[tl_cfg_func*32 +: 32] <= tl_cfg_ctl; + end + 5'h06: begin + cfg_msi_data[tl_cfg_func*16 +: 16] <= tl_cfg_ctl[31:16]; + cfg_send_f_err[tl_cfg_func +: 1] <= tl_cfg_ctl[15]; + cfg_send_nf_err[tl_cfg_func +: 1] <= tl_cfg_ctl[14]; + cfg_send_cor_err[tl_cfg_func +: 1] <= tl_cfg_ctl[13]; + cfg_aer_irq_msg_num[tl_cfg_func*5 +: 5] <= tl_cfg_ctl[12:8]; + cfg_msix_func_mask[tl_cfg_func +: 1] <= tl_cfg_ctl[6]; + cfg_msix_enable[tl_cfg_func +: 1] <= tl_cfg_ctl[5]; + cfg_multiple_msi_enable[tl_cfg_func*3 +: 3] <= tl_cfg_ctl[4:2]; + cfg_64bit_msi[tl_cfg_func +: 1] <= tl_cfg_ctl[1]; + cfg_msi_enable[tl_cfg_func +: 1] <= tl_cfg_ctl[0]; + end + 5'h07: begin + cfg_aer_uncor_err_mask[tl_cfg_func*32 +: 32] <= tl_cfg_ctl; + end + 5'h08: begin + cfg_aer_corr_err_mask[tl_cfg_func*32 +: 32] <= tl_cfg_ctl; + end + 5'h09: begin + cfg_aer_uncor_err_severity[tl_cfg_func*32 +: 32] <= tl_cfg_ctl; + end + endcase + end + end + + if (rst) begin + cfg_memory_space_en <= 0; + cfg_ido_cpl_en <= 0; + cfg_perr_en <= 0; + cfg_serr_en <= 0; + cfg_fatal_err_rpt_en <= 0; + cfg_nonfatal_err_rpt_en <= 0; + cfg_corr_err_rpt_en <= 0; + cfg_unsupported_req_rpt_en <= 0; + cfg_bus_master_en <= 0; + cfg_ext_tag_en <= 0; + cfg_max_read_request_size <= 0; + cfg_max_payload_size <= 0; + cfg_ido_request_en <= 0; + cfg_no_snoop_en <= 0; + cfg_relaxed_ordering_en <= 0; + cfg_device_num <= 0; + cfg_bus_num <= 0; + cfg_pm_no_soft_rst <= 0; + cfg_rcb_ctrl <= 0; + cfg_irq_disable <= 0; + cfg_pcie_cap_irq_msg_num <= 0; + cfg_sys_pwr_ctrl <= 0; + cfg_sys_atten_ind_ctrl <= 0; + cfg_sys_pwr_ind_ctrl <= 0; + cfg_num_vf <= 0; + cfg_ats_stu <= 0; + cfg_ats_cache_en <= 0; + cfg_ari_forward_en <= 0; + cfg_atomic_request_en <= 0; + cfg_tph_st_mode <= 0; + cfg_tph_en <= 0; + cfg_vf_en <= 0; + cfg_an_link_speed <= 0; + cfg_an_link_width <= 0; + cfg_start_vf_index <= 0; + cfg_msi_address <= 0; + cfg_msi_mask <= 0; + cfg_send_f_err <= 0; + cfg_send_nf_err <= 0; + cfg_send_cor_err <= 0; + cfg_aer_irq_msg_num <= 0; + cfg_msix_func_mask <= 0; + cfg_msix_enable <= 0; + cfg_multiple_msi_enable <= 0; + cfg_64bit_msi <= 0; + cfg_msi_enable <= 0; + cfg_msi_data <= 0; + cfg_aer_uncor_err_mask <= 0; + cfg_aer_corr_err_mask <= 0; + cfg_aer_uncor_err_severity <= 0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/rtl/pcie_s10_if.v b/fpga/lib/pcie/rtl/pcie_s10_if.v new file mode 100644 index 000000000..e714c20cd --- /dev/null +++ b/fpga/lib/pcie/rtl/pcie_s10_if.v @@ -0,0 +1,464 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Intel Stratix 10 H-Tile/L-Tile PCIe interface adapter + */ +module pcie_s10_if # +( + // H-Tile/L-Tile AVST segment count + parameter SEG_COUNT = 1, + // H-Tile/L-Tile AVST segment data width + parameter SEG_DATA_WIDTH = 256, + // H-Tile/L-Tile AVST segment empty signal width + parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32), + // TLP segment count + parameter TLP_SEG_COUNT = 1, + // TLP segment data width + parameter TLP_SEG_DATA_WIDTH = (SEG_COUNT*SEG_DATA_WIDTH)/TLP_SEG_COUNT, + // TLP segment strobe width + parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32, + // TLP segment header width + parameter TLP_SEG_HDR_WIDTH = 128, + // TX sequence number width + parameter TX_SEQ_NUM_WIDTH = 6, + // Tile selection (0 for H-Tile, 1 for L-Tile) + parameter L_TILE = 0, + // Number of PFs + parameter PF_COUNT = 1, + // Number of VFs + parameter VF_COUNT = 0, + // Total number of functions + parameter F_COUNT = PF_COUNT+VF_COUNT, + // IO bar index + // rx_st_bar_range = 6 is mapped to IO_BAR_INDEX on rx_req_tlp_bar_id + parameter IO_BAR_INDEX = 5, + // enable MSI support + parameter MSI_ENABLE = 1, + // MSI vector count + parameter MSI_COUNT = 32 +) +( + input wire clk, + input wire rst, + + /* + * H-Tile/L-Tile RX AVST interface + */ + input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data, + input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty, + input wire [SEG_COUNT-1:0] rx_st_sop, + input wire [SEG_COUNT-1:0] rx_st_eop, + input wire [SEG_COUNT-1:0] rx_st_valid, + output wire rx_st_ready, + input wire [SEG_COUNT-1:0] rx_st_vf_active, + input wire [SEG_COUNT*2-1:0] rx_st_func_num, + input wire [SEG_COUNT*11-1:0] rx_st_vf_num, + input wire [SEG_COUNT*3-1:0] rx_st_bar_range, + + /* + * H-Tile/L-Tile TX AVST interface + */ + output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data, + output wire [SEG_COUNT-1:0] tx_st_sop, + output wire [SEG_COUNT-1:0] tx_st_eop, + output wire [SEG_COUNT-1:0] tx_st_valid, + input wire tx_st_ready, + output wire [SEG_COUNT-1:0] tx_st_err, + + /* + * H-Tile/L-Tile TX flow control + */ + input wire [7:0] tx_ph_cdts, + input wire [11:0] tx_pd_cdts, + input wire [7:0] tx_nph_cdts, + input wire [11:0] tx_npd_cdts, + input wire [7:0] tx_cplh_cdts, + input wire [11:0] tx_cpld_cdts, + input wire [SEG_COUNT-1:0] tx_hdr_cdts_consumed, + input wire [SEG_COUNT-1:0] tx_data_cdts_consumed, + input wire [SEG_COUNT*2-1:0] tx_cdts_type, + input wire [SEG_COUNT*1-1:0] tx_cdts_data_value, + + /* + * H-Tile/L-Tile MSI interrupt interface + */ + output wire app_msi_req, + input wire app_msi_ack, + output wire [2:0] app_msi_tc, + output wire [4:0] app_msi_num, + output wire [1:0] app_msi_func_num, + + /* + * H-Tile/L-Tile configuration interface + */ + input wire [31:0] tl_cfg_ctl, + input wire [4:0] tl_cfg_add, + input wire [1:0] tl_cfg_func, + + /* + * TLP output (request to BAR) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_req_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_req_tlp_hdr, + output wire [TLP_SEG_COUNT*3-1:0] rx_req_tlp_bar_id, + output wire [TLP_SEG_COUNT*8-1:0] rx_req_tlp_func_num, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_eop, + input wire rx_req_tlp_ready, + + /* + * TLP output (completion to DMA) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_cpl_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_cpl_tlp_hdr, + output wire [TLP_SEG_COUNT*4-1:0] rx_cpl_tlp_error, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_eop, + input wire rx_cpl_tlp_ready, + + /* + * TLP input (read request from DMA) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_rd_req_tlp_hdr, + input wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_rd_req_tlp_seq, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_eop, + output wire tx_rd_req_tlp_ready, + + /* + * Transmit sequence number output (DMA read request) + */ + output wire [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_rd_req_tx_seq_num, + output wire [SEG_COUNT-1:0] m_axis_rd_req_tx_seq_num_valid, + + /* + * TLP input (write request from DMA) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_wr_req_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_wr_req_tlp_strb, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_wr_req_tlp_hdr, + input wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_wr_req_tlp_seq, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_eop, + output wire tx_wr_req_tlp_ready, + + /* + * Transmit sequence number output (DMA write request) + */ + output wire [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_wr_req_tx_seq_num, + output wire [SEG_COUNT-1:0] m_axis_wr_req_tx_seq_num_valid, + + /* + * TLP input (completion from BAR) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_cpl_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_cpl_tlp_strb, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_cpl_tlp_hdr, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_eop, + output wire tx_cpl_tlp_ready, + + /* + * Flow control + */ + output wire [7:0] tx_fc_ph_av, + output wire [11:0] tx_fc_pd_av, + output wire [7:0] tx_fc_nph_av, + output wire [11:0] tx_fc_npd_av, + output wire [7:0] tx_fc_cplh_av, + output wire [11:0] tx_fc_cpld_av, + + /* + * Configuration outputs + */ + output wire [F_COUNT-1:0] ext_tag_enable, + output wire [7:0] bus_num, + output wire [F_COUNT*3-1:0] max_read_request_size, + output wire [F_COUNT*3-1:0] max_payload_size, + + /* + * MSI request inputs + */ + input wire [MSI_COUNT-1:0] msi_irq +); + +wire [PF_COUNT-1:0] cfg_msi_enable; +wire [PF_COUNT*3-1:0] cfg_multiple_msi_enable; +wire [PF_COUNT*32-1:0] cfg_msi_mask; + +pcie_s10_if_rx #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .IO_BAR_INDEX(IO_BAR_INDEX) +) +pcie_s10_if_rx_inst ( + .clk(clk), + .rst(rst), + + /* + * H-Tile/L-Tile RX AVST interface + */ + .rx_st_data(rx_st_data), + .rx_st_empty(rx_st_empty), + .rx_st_sop(rx_st_sop), + .rx_st_eop(rx_st_eop), + .rx_st_valid(rx_st_valid), + .rx_st_ready(rx_st_ready), + .rx_st_vf_active(rx_st_vf_active), + .rx_st_func_num(rx_st_func_num), + .rx_st_vf_num(rx_st_vf_num), + .rx_st_bar_range(rx_st_bar_range), + + /* + * TLP output (request to BAR) + */ + .rx_req_tlp_data(rx_req_tlp_data), + .rx_req_tlp_hdr(rx_req_tlp_hdr), + .rx_req_tlp_bar_id(rx_req_tlp_bar_id), + .rx_req_tlp_func_num(rx_req_tlp_func_num), + .rx_req_tlp_valid(rx_req_tlp_valid), + .rx_req_tlp_sop(rx_req_tlp_sop), + .rx_req_tlp_eop(rx_req_tlp_eop), + .rx_req_tlp_ready(rx_req_tlp_ready), + + /* + * TLP output (completion to DMA) + */ + .rx_cpl_tlp_data(rx_cpl_tlp_data), + .rx_cpl_tlp_hdr(rx_cpl_tlp_hdr), + .rx_cpl_tlp_error(rx_cpl_tlp_error), + .rx_cpl_tlp_valid(rx_cpl_tlp_valid), + .rx_cpl_tlp_sop(rx_cpl_tlp_sop), + .rx_cpl_tlp_eop(rx_cpl_tlp_eop), + .rx_cpl_tlp_ready(rx_cpl_tlp_ready) +); + +pcie_s10_if_tx #( + .SEG_COUNT(SEG_COUNT), + .SEG_DATA_WIDTH(SEG_DATA_WIDTH), + .TLP_SEG_COUNT(TLP_SEG_COUNT), + .TLP_SEG_DATA_WIDTH(TLP_SEG_DATA_WIDTH), + .TLP_SEG_STRB_WIDTH(TLP_SEG_STRB_WIDTH), + .TLP_SEG_HDR_WIDTH(TLP_SEG_HDR_WIDTH), + .TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH) +) +pcie_s10_if_tx_inst ( + .clk(clk), + .rst(rst), + + /* + * H-Tile/L-Tile TX AVST interface + */ + .tx_st_data(tx_st_data), + .tx_st_sop(tx_st_sop), + .tx_st_eop(tx_st_eop), + .tx_st_valid(tx_st_valid), + .tx_st_ready(tx_st_ready), + .tx_st_err(tx_st_err), + + /* + * TLP input (read request from DMA) + */ + .tx_rd_req_tlp_hdr(tx_rd_req_tlp_hdr), + .tx_rd_req_tlp_seq(tx_rd_req_tlp_seq), + .tx_rd_req_tlp_valid(tx_rd_req_tlp_valid), + .tx_rd_req_tlp_sop(tx_rd_req_tlp_sop), + .tx_rd_req_tlp_eop(tx_rd_req_tlp_eop), + .tx_rd_req_tlp_ready(tx_rd_req_tlp_ready), + + /* + * Transmit sequence number output (DMA read request) + */ + .m_axis_rd_req_tx_seq_num(m_axis_rd_req_tx_seq_num), + .m_axis_rd_req_tx_seq_num_valid(m_axis_rd_req_tx_seq_num_valid), + + /* + * TLP input (write request from DMA) + */ + .tx_wr_req_tlp_data(tx_wr_req_tlp_data), + .tx_wr_req_tlp_strb(tx_wr_req_tlp_strb), + .tx_wr_req_tlp_hdr(tx_wr_req_tlp_hdr), + .tx_wr_req_tlp_seq(tx_wr_req_tlp_seq), + .tx_wr_req_tlp_valid(tx_wr_req_tlp_valid), + .tx_wr_req_tlp_sop(tx_wr_req_tlp_sop), + .tx_wr_req_tlp_eop(tx_wr_req_tlp_eop), + .tx_wr_req_tlp_ready(tx_wr_req_tlp_ready), + + /* + * Transmit sequence number output (DMA write request) + */ + .m_axis_wr_req_tx_seq_num(m_axis_wr_req_tx_seq_num), + .m_axis_wr_req_tx_seq_num_valid(m_axis_wr_req_tx_seq_num_valid), + + /* + * TLP input (completion from BAR) + */ + .tx_cpl_tlp_data(tx_cpl_tlp_data), + .tx_cpl_tlp_strb(tx_cpl_tlp_strb), + .tx_cpl_tlp_hdr(tx_cpl_tlp_hdr), + .tx_cpl_tlp_valid(tx_cpl_tlp_valid), + .tx_cpl_tlp_sop(tx_cpl_tlp_sop), + .tx_cpl_tlp_eop(tx_cpl_tlp_eop), + .tx_cpl_tlp_ready(tx_cpl_tlp_ready) +); + +pcie_s10_cfg #( + .L_TILE(L_TILE), + .PF_COUNT(PF_COUNT) +) +pcie_s10_cfg_inst ( + .clk(clk), + .rst(rst), + + /* + * Configuration input from H-Tile/L-Tile + */ + .tl_cfg_ctl(tl_cfg_ctl), + .tl_cfg_add(tl_cfg_add), + .tl_cfg_func(tl_cfg_func), + + /* + * Configuration output + */ + .cfg_memory_space_en(), + .cfg_ido_cpl_en(), + .cfg_perr_en(), + .cfg_serr_en(), + .cfg_fatal_err_rpt_en(), + .cfg_nonfatal_err_rpt_en(), + .cfg_corr_err_rpt_en(), + .cfg_unsupported_req_rpt_en(), + .cfg_bus_master_en(), + .cfg_ext_tag_en(ext_tag_enable), + .cfg_max_read_request_size(max_read_request_size), + .cfg_max_payload_size(max_payload_size), + .cfg_ido_request_en(), + .cfg_no_snoop_en(), + .cfg_relaxed_ordering_en(), + .cfg_device_num(), + .cfg_bus_num(bus_num), + .cfg_pm_no_soft_rst(), + .cfg_rcb_ctrl(), + .cfg_irq_disable(), + .cfg_pcie_cap_irq_msg_num(), + .cfg_sys_pwr_ctrl(), + .cfg_sys_atten_ind_ctrl(), + .cfg_sys_pwr_ind_ctrl(), + .cfg_num_vf(), + .cfg_ats_stu(), + .cfg_ats_cache_en(), + .cfg_ari_forward_en(), + .cfg_atomic_request_en(), + .cfg_tph_st_mode(), + .cfg_tph_en(), + .cfg_vf_en(), + .cfg_an_link_speed(), + .cfg_start_vf_index(), + .cfg_msi_address(), + .cfg_msi_mask(cfg_msi_mask), + .cfg_send_f_err(), + .cfg_send_nf_err(), + .cfg_send_cor_err(), + .cfg_aer_irq_msg_num(), + .cfg_msix_func_mask(), + .cfg_msix_enable(), + .cfg_multiple_msi_enable(cfg_multiple_msi_enable), + .cfg_64bit_msi(), + .cfg_msi_enable(cfg_msi_enable), + .cfg_msi_data(), + .cfg_aer_uncor_err_mask(), + .cfg_aer_corr_err_mask(), + .cfg_aer_uncor_err_severity() +); + +assign tx_fc_ph_av = tx_ph_cdts; +assign tx_fc_pd_av = tx_pd_cdts; +assign tx_fc_nph_av = tx_nph_cdts; +assign tx_fc_npd_av = L_TILE ? tx_npd_cdts : 0; +assign tx_fc_cplh_av = tx_cplh_cdts; +assign tx_fc_cpld_av = L_TILE ? tx_cpld_cdts : 0; + +generate + +if (MSI_ENABLE) begin + + pcie_s10_msi #( + .MSI_COUNT(MSI_COUNT) + ) + pcie_s10_msi_inst ( + .clk(clk), + .rst(rst), + + /* + * Interrupt request inputs + */ + .msi_irq(msi_irq), + + /* + * Interface to H-Tile/L-Tile PCIe IP core + */ + .app_msi_req(app_msi_req), + .app_msi_ack(app_msi_ack), + .app_msi_tc(app_msi_tc), + .app_msi_num(app_msi_num), + .app_msi_func_num(app_msi_func_num), + + /* + * Configuration + */ + .cfg_msi_enable(cfg_msi_enable), + .cfg_multiple_msi_enable(cfg_multiple_msi_enable), + .cfg_msi_mask(cfg_msi_mask) + ); + +end else begin + + assign app_msi_req = 0; + assign app_msi_tc = 0; + assign app_msi_num = 0; + assign app_msi_func_num = 0; + +end + +endgenerate + +endmodule + +`resetall diff --git a/fpga/lib/pcie/rtl/pcie_s10_if_rx.v b/fpga/lib/pcie/rtl/pcie_s10_if_rx.v new file mode 100644 index 000000000..fe4d24ed7 --- /dev/null +++ b/fpga/lib/pcie/rtl/pcie_s10_if_rx.v @@ -0,0 +1,459 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Intel Stratix 10 H-Tile/L-Tile PCIe interface adapter (receive) + */ +module pcie_s10_if_rx # +( + // H-Tile/L-Tile AVST segment count + parameter SEG_COUNT = 1, + // H-Tile/L-Tile AVST segment data width + parameter SEG_DATA_WIDTH = 256, + // H-Tile/L-Tile AVST segment empty signal width + parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32), + // TLP segment count + parameter TLP_SEG_COUNT = 1, + // TLP segment data width + parameter TLP_SEG_DATA_WIDTH = (SEG_COUNT*SEG_DATA_WIDTH)/TLP_SEG_COUNT, + // TLP segment strobe width + parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32, + // TLP segment header width + parameter TLP_SEG_HDR_WIDTH = 128, + // IO bar index + // rx_st_bar_range = 6 is mapped to IO_BAR_INDEX on rx_req_tlp_bar_id + parameter IO_BAR_INDEX = 5 +) +( + input wire clk, + input wire rst, + + // H-Tile/L-Tile RX AVST interface + input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data, + input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty, + input wire [SEG_COUNT-1:0] rx_st_sop, + input wire [SEG_COUNT-1:0] rx_st_eop, + input wire [SEG_COUNT-1:0] rx_st_valid, + output wire rx_st_ready, + input wire [SEG_COUNT-1:0] rx_st_vf_active, + input wire [SEG_COUNT*2-1:0] rx_st_func_num, + input wire [SEG_COUNT*11-1:0] rx_st_vf_num, + input wire [SEG_COUNT*3-1:0] rx_st_bar_range, + + /* + * TLP output (request to BAR) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_req_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_req_tlp_hdr, + output wire [TLP_SEG_COUNT*3-1:0] rx_req_tlp_bar_id, + output wire [TLP_SEG_COUNT*8-1:0] rx_req_tlp_func_num, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] rx_req_tlp_eop, + input wire rx_req_tlp_ready, + + /* + * TLP output (completion to DMA) + */ + output wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_cpl_tlp_data, + output wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_cpl_tlp_hdr, + output wire [TLP_SEG_COUNT*4-1:0] rx_cpl_tlp_error, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_valid, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_sop, + output wire [TLP_SEG_COUNT-1:0] rx_cpl_tlp_eop, + input wire rx_cpl_tlp_ready +); + +parameter OUTPUT_FIFO_ADDR_WIDTH = 5; +parameter OUTPUT_FIFO_LIMIT = 8; + +// bus width assertions +initial begin + if (SEG_COUNT != 1) begin + $error("Error: segment count must be 1 (instance %m)"); + $finish; + end + + if (SEG_DATA_WIDTH != 256) begin + $error("Error: segment data width must be 256 (instance %m)"); + $finish; + end + + if (TLP_SEG_COUNT != 1) begin + $error("Error: TLP segment count must be 1 (instance %m)"); + $finish; + end + + if (TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH != SEG_COUNT*SEG_DATA_WIDTH) begin + $error("Error: Interface widths must match (instance %m)"); + $finish; + end + + if (TLP_SEG_HDR_WIDTH != 128) begin + $error("Error: TLP segment header width must be 128 (instance %m)"); + $finish; + end +end + +localparam [1:0] + TLP_INPUT_STATE_IDLE = 2'd0, + TLP_INPUT_STATE_HEADER = 2'd1, + TLP_INPUT_STATE_PAYLOAD = 2'd2; + +reg [1:0] tlp_input_state_reg = TLP_INPUT_STATE_IDLE, tlp_input_state_next; + +reg payload_offset_reg = 0, payload_offset_next; + +reg cpl_reg = 1'b0, cpl_next; + +// internal datapath +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_req_tlp_data_int; +reg [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_req_tlp_hdr_int; +reg [TLP_SEG_COUNT*3-1:0] rx_req_tlp_bar_id_int; +reg [TLP_SEG_COUNT*8-1:0] rx_req_tlp_func_num_int; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_sop_int; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_eop_int; +wire rx_req_tlp_ready_int; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_valid_int; +wire rx_cpl_tlp_ready_int; +reg [TLP_SEG_COUNT-1:0] rx_cpl_tlp_valid_int; + +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data_int_reg = 0, rx_st_data_int_next; +reg [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty_int_reg = 0, rx_st_empty_int_next; +reg [SEG_COUNT-1:0] rx_st_sop_int_reg = 0, rx_st_sop_int_next; +reg [SEG_COUNT-1:0] rx_st_eop_int_reg = 0, rx_st_eop_int_next; +reg [SEG_COUNT-1:0] rx_st_valid_int_reg = 0, rx_st_valid_int_next; +reg [SEG_COUNT-1:0] rx_st_vf_active_int_reg = 0, rx_st_vf_active_int_next; +reg [SEG_COUNT*2-1:0] rx_st_func_num_int_reg = 0, rx_st_func_num_int_next; +reg [SEG_COUNT*11-1:0] rx_st_vf_num_int_reg = 0, rx_st_vf_num_int_next; +reg [SEG_COUNT*3-1:0] rx_st_bar_range_int_reg = 0, rx_st_bar_range_int_next; + +wire [SEG_COUNT*SEG_DATA_WIDTH*2-1:0] rx_st_data_full = {rx_st_data, rx_st_data_int_reg}; + +assign rx_st_ready = rx_req_tlp_ready_int && rx_cpl_tlp_ready_int; + +always @* begin + tlp_input_state_next = TLP_INPUT_STATE_IDLE; + + payload_offset_next = payload_offset_reg; + + cpl_next = cpl_reg; + + if (payload_offset_reg) begin + rx_req_tlp_data_int = rx_st_data_full[SEG_COUNT*SEG_DATA_WIDTH+128-1:128]; + end else begin + rx_req_tlp_data_int = rx_st_data_full[SEG_COUNT*SEG_DATA_WIDTH+96-1:96]; + end + rx_req_tlp_hdr_int[127:96] = rx_st_data_full[31:0]; + rx_req_tlp_hdr_int[95:64] = rx_st_data_full[63:32]; + rx_req_tlp_hdr_int[63:32] = rx_st_data_full[95:64]; + rx_req_tlp_hdr_int[31:0] = rx_st_data_full[127:96]; + if (rx_st_bar_range == 6) begin + // IO BAR + rx_req_tlp_bar_id_int = IO_BAR_INDEX; + end else if (rx_st_bar_range == 7) begin + // expansion ROM BAR + rx_req_tlp_bar_id_int = 6; + end else begin + // memory BAR + rx_req_tlp_bar_id_int = rx_st_bar_range; + end + rx_req_tlp_func_num_int = rx_st_func_num; + rx_req_tlp_valid_int = 1'b0; + rx_req_tlp_sop_int = 1'b1; + rx_req_tlp_eop_int = 1'b1; + rx_cpl_tlp_valid_int = 1'b0; + + rx_st_data_int_next = rx_st_data_int_reg; + rx_st_empty_int_next = rx_st_empty_int_reg; + rx_st_sop_int_next = rx_st_sop_int_reg; + rx_st_eop_int_next = rx_st_eop_int_reg; + rx_st_valid_int_next = rx_st_valid_int_reg; + rx_st_vf_active_int_next = rx_st_vf_active_int_reg; + rx_st_func_num_int_next = rx_st_func_num_int_reg; + rx_st_vf_num_int_next = rx_st_vf_num_int_reg; + rx_st_bar_range_int_next = rx_st_bar_range_int_reg; + + case (tlp_input_state_reg) + TLP_INPUT_STATE_IDLE: begin + if (rx_st_valid_int_reg) begin + rx_req_tlp_hdr_int[127:96] = rx_st_data_full[31:0]; + rx_req_tlp_hdr_int[95:64] = rx_st_data_full[63:32]; + rx_req_tlp_hdr_int[63:32] = rx_st_data_full[95:64]; + rx_req_tlp_hdr_int[31:0] = rx_st_data_full[127:96]; + + payload_offset_next = rx_st_data_full[29]; + + if (rx_st_bar_range == 6) begin + // IO BAR + rx_req_tlp_bar_id_int = IO_BAR_INDEX; + end else if (rx_st_bar_range == 7) begin + // expansion ROM BAR + rx_req_tlp_bar_id_int = 6; + end else begin + // memory BAR + rx_req_tlp_bar_id_int = rx_st_bar_range; + end + rx_req_tlp_func_num_int = rx_st_func_num; + + if (payload_offset_next) begin + rx_req_tlp_data_int = rx_st_data_full[(SEG_COUNT*SEG_DATA_WIDTH)+128-1:128]; + end else begin + rx_req_tlp_data_int = rx_st_data_full[(SEG_COUNT*SEG_DATA_WIDTH)+96-1:96]; + end + rx_req_tlp_sop_int = 1'b1; + rx_req_tlp_eop_int = 1'b0; + + cpl_next = !rx_st_data_full[29] && rx_st_data_full[28:25] == 4'b0101; + + if (rx_st_eop_int_reg) begin + rx_req_tlp_valid_int = !cpl_next; + rx_cpl_tlp_valid_int = cpl_next; + rx_req_tlp_eop_int = 1'b1; + rx_st_valid_int_next = 1'b0; + tlp_input_state_next = TLP_INPUT_STATE_IDLE; + end else if (rx_st_valid) begin + rx_req_tlp_valid_int = !cpl_next; + rx_cpl_tlp_valid_int = cpl_next; + tlp_input_state_next = TLP_INPUT_STATE_PAYLOAD; + end else begin + tlp_input_state_next = TLP_INPUT_STATE_IDLE; + end + end else begin + tlp_input_state_next = TLP_INPUT_STATE_IDLE; + end + end + TLP_INPUT_STATE_PAYLOAD: begin + if (rx_st_valid_int_reg) begin + + if (payload_offset_reg) begin + rx_req_tlp_data_int = rx_st_data_full[SEG_COUNT*SEG_DATA_WIDTH+128-1:128]; + end else begin + rx_req_tlp_data_int = rx_st_data_full[SEG_COUNT*SEG_DATA_WIDTH+96-1:96]; + end + rx_req_tlp_sop_int = 1'b0; + rx_req_tlp_eop_int = 1'b0; + + if (rx_st_eop_int_reg) begin + rx_req_tlp_valid_int = !cpl_reg; + rx_cpl_tlp_valid_int = cpl_reg; + rx_req_tlp_eop_int = 1'b1; + rx_st_valid_int_next = 1'b0; + tlp_input_state_next = TLP_INPUT_STATE_IDLE; + end else if (rx_st_valid) begin + rx_req_tlp_valid_int = !cpl_reg; + rx_cpl_tlp_valid_int = cpl_reg; + tlp_input_state_next = TLP_INPUT_STATE_PAYLOAD; + end else begin + tlp_input_state_next = TLP_INPUT_STATE_PAYLOAD; + end + end else begin + tlp_input_state_next = TLP_INPUT_STATE_PAYLOAD; + end + end + endcase + + if (rx_st_valid) begin + rx_st_data_int_next = rx_st_data; + rx_st_empty_int_next = rx_st_empty; + rx_st_sop_int_next = rx_st_sop; + rx_st_eop_int_next = rx_st_eop; + rx_st_valid_int_next = rx_st_valid; + rx_st_vf_active_int_next = rx_st_vf_active; + rx_st_func_num_int_next = rx_st_func_num; + rx_st_vf_num_int_next = rx_st_vf_num; + rx_st_bar_range_int_next = rx_st_bar_range; + end +end + +always @(posedge clk) begin + tlp_input_state_reg <= tlp_input_state_next; + + payload_offset_reg <= payload_offset_next; + + cpl_reg <= cpl_next; + + rx_st_data_int_reg <= rx_st_data_int_next; + rx_st_empty_int_reg <= rx_st_empty_int_next; + rx_st_sop_int_reg <= rx_st_sop_int_next; + rx_st_eop_int_reg <= rx_st_eop_int_next; + rx_st_valid_int_reg <= rx_st_valid_int_next; + rx_st_vf_active_int_reg <= rx_st_vf_active_int_next; + rx_st_func_num_int_reg <= rx_st_func_num_int_next; + rx_st_vf_num_int_reg <= rx_st_vf_num_int_next; + rx_st_bar_range_int_reg <= rx_st_bar_range_int_next; + + if (rst) begin + tlp_input_state_reg <= TLP_INPUT_STATE_IDLE; + + rx_st_valid_int_reg <= 1'b0; + end +end + +// output datapath logic (request TLP) +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_req_tlp_data_reg = 0; +reg [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_req_tlp_hdr_reg = 0; +reg [TLP_SEG_COUNT*3-1:0] rx_req_tlp_bar_id_reg = 0; +reg [TLP_SEG_COUNT*8-1:0] rx_req_tlp_func_num_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_valid_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_sop_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_req_tlp_eop_reg = 0; + +reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_req_fifo_wr_ptr_reg = 0; +reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_req_fifo_rd_ptr_reg = 0; +reg out_req_fifo_watermark_reg = 1'b0; + +wire out_req_fifo_full = out_req_fifo_wr_ptr_reg == (out_req_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); +wire out_req_fifo_empty = out_req_fifo_wr_ptr_reg == out_req_fifo_rd_ptr_reg; + +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] out_req_fifo_rx_req_tlp_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] out_req_fifo_rx_req_tlp_hdr[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*3-1:0] out_req_fifo_rx_req_tlp_bar_id[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*8-1:0] out_req_fifo_rx_req_tlp_func_num[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_req_fifo_rx_req_tlp_valid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_req_fifo_rx_req_tlp_sop[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_req_fifo_rx_req_tlp_eop[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + +assign rx_req_tlp_ready_int = !out_req_fifo_watermark_reg; + +assign rx_req_tlp_data = rx_req_tlp_data_reg; +assign rx_req_tlp_hdr = rx_req_tlp_hdr_reg; +assign rx_req_tlp_bar_id = rx_req_tlp_bar_id_reg; +assign rx_req_tlp_func_num = rx_req_tlp_func_num_reg; +assign rx_req_tlp_valid = rx_req_tlp_valid_reg; +assign rx_req_tlp_sop = rx_req_tlp_sop_reg; +assign rx_req_tlp_eop = rx_req_tlp_eop_reg; + +always @(posedge clk) begin + rx_req_tlp_valid_reg <= rx_req_tlp_valid_reg && !rx_req_tlp_ready; + + out_req_fifo_watermark_reg <= $unsigned(out_req_fifo_wr_ptr_reg - out_req_fifo_rd_ptr_reg) >= OUTPUT_FIFO_LIMIT; + + if (!out_req_fifo_full && rx_req_tlp_valid_int) begin + out_req_fifo_rx_req_tlp_data[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_data_int; + out_req_fifo_rx_req_tlp_hdr[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_hdr_int; + out_req_fifo_rx_req_tlp_bar_id[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_bar_id_int; + out_req_fifo_rx_req_tlp_func_num[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_func_num_int; + out_req_fifo_rx_req_tlp_sop[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_sop_int; + out_req_fifo_rx_req_tlp_eop[out_req_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_eop_int; + out_req_fifo_wr_ptr_reg <= out_req_fifo_wr_ptr_reg + 1; + end + + if (!out_req_fifo_empty && (!rx_req_tlp_valid_reg || rx_req_tlp_ready)) begin + rx_req_tlp_data_reg <= out_req_fifo_rx_req_tlp_data[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_hdr_reg <= out_req_fifo_rx_req_tlp_hdr[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_bar_id_reg <= out_req_fifo_rx_req_tlp_bar_id[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_func_num_reg <= out_req_fifo_rx_req_tlp_func_num[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_sop_reg <= out_req_fifo_rx_req_tlp_sop[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_eop_reg <= out_req_fifo_rx_req_tlp_eop[out_req_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_req_tlp_valid_reg <= 1'b1; + out_req_fifo_rd_ptr_reg <= out_req_fifo_rd_ptr_reg + 1; + end + + if (rst) begin + out_req_fifo_wr_ptr_reg <= 0; + out_req_fifo_rd_ptr_reg <= 0; + rx_req_tlp_valid_reg <= 1'b0; + end +end + +// output datapath logic (completion TLP) +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] rx_cpl_tlp_data_reg = 0; +reg [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] rx_cpl_tlp_hdr_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_cpl_tlp_valid_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_cpl_tlp_sop_reg = 0; +reg [TLP_SEG_COUNT-1:0] rx_cpl_tlp_eop_reg = 0; + +reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_cpl_fifo_wr_ptr_reg = 0; +reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_cpl_fifo_rd_ptr_reg = 0; +reg out_cpl_fifo_watermark_reg = 1'b0; + +wire out_cpl_fifo_full = out_cpl_fifo_wr_ptr_reg == (out_cpl_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); +wire out_cpl_fifo_empty = out_cpl_fifo_wr_ptr_reg == out_cpl_fifo_rd_ptr_reg; + +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] out_cpl_fifo_rx_cpl_tlp_data[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] out_cpl_fifo_rx_cpl_tlp_hdr[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_cpl_fifo_rx_cpl_tlp_valid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_cpl_fifo_rx_cpl_tlp_sop[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TLP_SEG_COUNT-1:0] out_cpl_fifo_rx_cpl_tlp_eop[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + +assign rx_cpl_tlp_ready_int = !out_cpl_fifo_watermark_reg; + +assign rx_cpl_tlp_data = rx_cpl_tlp_data_reg; +assign rx_cpl_tlp_hdr = rx_cpl_tlp_hdr_reg; +assign rx_cpl_tlp_error = 0; +assign rx_cpl_tlp_valid = rx_cpl_tlp_valid_reg; +assign rx_cpl_tlp_sop = rx_cpl_tlp_sop_reg; +assign rx_cpl_tlp_eop = rx_cpl_tlp_eop_reg; + +always @(posedge clk) begin + rx_cpl_tlp_valid_reg <= rx_cpl_tlp_valid_reg && !rx_cpl_tlp_ready; + + out_cpl_fifo_watermark_reg <= $unsigned(out_cpl_fifo_wr_ptr_reg - out_cpl_fifo_rd_ptr_reg) >= OUTPUT_FIFO_LIMIT; + + if (!out_cpl_fifo_full && rx_cpl_tlp_valid_int) begin + out_cpl_fifo_rx_cpl_tlp_data[out_cpl_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_data_int; + out_cpl_fifo_rx_cpl_tlp_hdr[out_cpl_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_hdr_int; + out_cpl_fifo_rx_cpl_tlp_sop[out_cpl_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_sop_int; + out_cpl_fifo_rx_cpl_tlp_eop[out_cpl_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= rx_req_tlp_eop_int; + out_cpl_fifo_wr_ptr_reg <= out_cpl_fifo_wr_ptr_reg + 1; + end + + if (!out_cpl_fifo_empty && (!rx_cpl_tlp_valid_reg || rx_cpl_tlp_ready)) begin + rx_cpl_tlp_data_reg <= out_cpl_fifo_rx_cpl_tlp_data[out_cpl_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_cpl_tlp_hdr_reg <= out_cpl_fifo_rx_cpl_tlp_hdr[out_cpl_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_cpl_tlp_sop_reg <= out_cpl_fifo_rx_cpl_tlp_sop[out_cpl_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_cpl_tlp_eop_reg <= out_cpl_fifo_rx_cpl_tlp_eop[out_cpl_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + rx_cpl_tlp_valid_reg <= 1'b1; + out_cpl_fifo_rd_ptr_reg <= out_cpl_fifo_rd_ptr_reg + 1; + end + + if (rst) begin + out_cpl_fifo_wr_ptr_reg <= 0; + out_cpl_fifo_rd_ptr_reg <= 0; + rx_cpl_tlp_valid_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/rtl/pcie_s10_if_tx.v b/fpga/lib/pcie/rtl/pcie_s10_if_tx.v new file mode 100644 index 000000000..6cec15d1a --- /dev/null +++ b/fpga/lib/pcie/rtl/pcie_s10_if_tx.v @@ -0,0 +1,733 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Intel Stratix 10 H-Tile/L-Tile PCIe interface adapter (transmit) + */ +module pcie_s10_if_tx # +( + // H-Tile/L-Tile AVST segment count + parameter SEG_COUNT = 1, + // H-Tile/L-Tile AVST segment data width + parameter SEG_DATA_WIDTH = 256, + // TLP segment count + parameter TLP_SEG_COUNT = 1, + // TLP segment data width + parameter TLP_SEG_DATA_WIDTH = (SEG_COUNT*SEG_DATA_WIDTH)/TLP_SEG_COUNT, + // TLP segment strobe width + parameter TLP_SEG_STRB_WIDTH = TLP_SEG_DATA_WIDTH/32, + // TLP segment header width + parameter TLP_SEG_HDR_WIDTH = 128, + // TX sequence number width + parameter TX_SEQ_NUM_WIDTH = 6 +) +( + input wire clk, + input wire rst, + + // H-Tile/L-Tile TX AVST interface + output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data, + output wire [SEG_COUNT-1:0] tx_st_sop, + output wire [SEG_COUNT-1:0] tx_st_eop, + output wire [SEG_COUNT-1:0] tx_st_valid, + input wire tx_st_ready, + output wire [SEG_COUNT-1:0] tx_st_err, + + /* + * TLP input (read request from DMA) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_rd_req_tlp_hdr, + input wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_rd_req_tlp_seq, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_rd_req_tlp_eop, + output wire tx_rd_req_tlp_ready, + + /* + * Transmit sequence number output (DMA read request) + */ + output wire [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_rd_req_tx_seq_num, + output wire [SEG_COUNT-1:0] m_axis_rd_req_tx_seq_num_valid, + + /* + * TLP input (write request from DMA) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_wr_req_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_wr_req_tlp_strb, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_wr_req_tlp_hdr, + input wire [TLP_SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] tx_wr_req_tlp_seq, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_wr_req_tlp_eop, + output wire tx_wr_req_tlp_ready, + + /* + * Transmit sequence number output (DMA write request) + */ + output wire [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_wr_req_tx_seq_num, + output wire [SEG_COUNT-1:0] m_axis_wr_req_tx_seq_num_valid, + + /* + * TLP input (completion from BAR) + */ + input wire [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] tx_cpl_tlp_data, + input wire [TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH-1:0] tx_cpl_tlp_strb, + input wire [TLP_SEG_COUNT*TLP_SEG_HDR_WIDTH-1:0] tx_cpl_tlp_hdr, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_valid, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_sop, + input wire [TLP_SEG_COUNT-1:0] tx_cpl_tlp_eop, + output wire tx_cpl_tlp_ready +); + +parameter TLP_DATA_WIDTH = TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH; +parameter TLP_STRB_WIDTH = TLP_SEG_COUNT*TLP_SEG_STRB_WIDTH; +parameter TLP_DATA_WIDTH_BYTES = TLP_DATA_WIDTH/8; +parameter TLP_DATA_WIDTH_DWORDS = TLP_DATA_WIDTH/32; + +parameter FIFO_ADDR_WIDTH = 5; + +// bus width assertions +initial begin + if (SEG_COUNT != 1) begin + $error("Error: segment count must be 1 (instance %m)"); + $finish; + end + + if (SEG_DATA_WIDTH != 256) begin + $error("Error: segment data width must be 256 (instance %m)"); + $finish; + end + + if (TLP_SEG_COUNT != 1) begin + $error("Error: TLP segment count must be 1 (instance %m)"); + $finish; + end + + if (TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH != SEG_COUNT*SEG_DATA_WIDTH) begin + $error("Error: Interface widths must match (instance %m)"); + $finish; + end + + if (TLP_SEG_HDR_WIDTH != 128) begin + $error("Error: TLP segment header width must be 128 (instance %m)"); + $finish; + end +end + +localparam [0:0] + WR_REQ_STATE_IDLE = 1'd0, + WR_REQ_STATE_PAYLOAD = 1'd1; + +reg [0:0] wr_req_state_reg = WR_REQ_STATE_IDLE, wr_req_state_next; + +localparam [0:0] + CPL_STATE_IDLE = 1'd0, + CPL_STATE_PAYLOAD = 1'd1; + +reg [0:0] cpl_state_reg = CPL_STATE_IDLE, cpl_state_next; + +localparam [1:0] + TLP_OUTPUT_STATE_IDLE = 2'd0, + TLP_OUTPUT_STATE_WR_PAYLOAD = 2'd1, + TLP_OUTPUT_STATE_CPL_PAYLOAD = 2'd2; + +reg [1:0] tlp_output_state_reg = TLP_OUTPUT_STATE_IDLE, tlp_output_state_next; + +reg wr_req_payload_offset_reg = 1'b0, wr_req_payload_offset_next; + +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] wr_req_tlp_data_reg = 0, wr_req_tlp_data_next; +reg [TLP_SEG_COUNT-1:0] wr_req_tlp_eop_reg = 0, wr_req_tlp_eop_next; + +reg [TLP_SEG_COUNT*TLP_SEG_DATA_WIDTH-1:0] cpl_tlp_data_reg = 0, cpl_tlp_data_next; +reg [TLP_SEG_COUNT-1:0] cpl_tlp_eop_reg = 0, cpl_tlp_eop_next; + +reg tx_rd_req_tlp_ready_reg = 1'b0, tx_rd_req_tlp_ready_next; +reg tx_wr_req_tlp_ready_reg = 1'b0, tx_wr_req_tlp_ready_next; +reg tx_cpl_tlp_ready_reg = 1'b0, tx_cpl_tlp_ready_next; + +reg [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_rd_req_tx_seq_num_reg = 0, m_axis_rd_req_tx_seq_num_next; +reg [SEG_COUNT-1:0] m_axis_rd_req_tx_seq_num_valid_reg = 0, m_axis_rd_req_tx_seq_num_valid_next; +reg [SEG_COUNT*TX_SEQ_NUM_WIDTH-1:0] m_axis_wr_req_tx_seq_num_reg = 0, m_axis_wr_req_tx_seq_num_next; +reg [SEG_COUNT-1:0] m_axis_wr_req_tx_seq_num_valid_reg = 0, m_axis_wr_req_tx_seq_num_valid_next; + +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data_reg = 0, tx_st_data_next; +reg [SEG_COUNT-1:0] tx_st_sop_reg = 0, tx_st_sop_next; +reg [SEG_COUNT-1:0] tx_st_eop_reg = 0, tx_st_eop_next; +reg [SEG_COUNT-1:0] tx_st_valid_reg = 0, tx_st_valid_next; + +reg [1:0] tx_st_ready_delay_reg = 0; + +assign tx_rd_req_tlp_ready = tx_rd_req_tlp_ready_reg; +assign tx_wr_req_tlp_ready = tx_wr_req_tlp_ready_reg; +assign tx_cpl_tlp_ready = tx_cpl_tlp_ready_reg; + +assign m_axis_rd_req_tx_seq_num = m_axis_rd_req_tx_seq_num_reg; +assign m_axis_rd_req_tx_seq_num_valid = m_axis_rd_req_tx_seq_num_valid_reg; +assign m_axis_wr_req_tx_seq_num = m_axis_wr_req_tx_seq_num_reg; +assign m_axis_wr_req_tx_seq_num_valid = m_axis_wr_req_tx_seq_num_valid_reg; + +assign tx_st_data = tx_st_data_reg; +assign tx_st_sop = tx_st_sop_reg; +assign tx_st_eop = tx_st_eop_reg; +assign tx_st_valid = tx_st_valid_reg; +assign tx_st_err = 0; + +// read request FIFO +reg [FIFO_ADDR_WIDTH+1-1:0] rd_req_fifo_wr_ptr_reg = 0; +reg [FIFO_ADDR_WIDTH+1-1:0] rd_req_fifo_rd_ptr_reg = 0, rd_req_fifo_rd_ptr_next; + +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_DATA_WIDTH-1:0] rd_req_fifo_data[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TX_SEQ_NUM_WIDTH-1:0] rd_req_fifo_seq[(2**FIFO_ADDR_WIDTH)-1:0]; + +reg [SEG_DATA_WIDTH-1:0] rd_req_fifo_wr_data; +reg [TX_SEQ_NUM_WIDTH-1:0] rd_req_fifo_wr_seq; +reg rd_req_fifo_we; + +reg rd_req_fifo_watermark_reg = 1'b0; +reg [SEG_DATA_WIDTH-1:0] rd_req_fifo_rd_data_reg = 0, rd_req_fifo_rd_data_next; +reg rd_req_fifo_rd_valid_reg = 0, rd_req_fifo_rd_valid_next; +reg [TX_SEQ_NUM_WIDTH-1:0] rd_req_fifo_rd_seq_reg = 0, rd_req_fifo_rd_seq_next; + +// write request FIFO +reg [FIFO_ADDR_WIDTH+1-1:0] wr_req_fifo_wr_ptr_reg = 0; +reg [FIFO_ADDR_WIDTH+1-1:0] wr_req_fifo_wr_ptr_cur_reg = 0; +reg [FIFO_ADDR_WIDTH+1-1:0] wr_req_fifo_rd_ptr_reg = 0, wr_req_fifo_rd_ptr_next; + +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] wr_req_fifo_data[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT-1:0] wr_req_fifo_eop[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT-1:0] wr_req_fifo_valid[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [TX_SEQ_NUM_WIDTH-1:0] wr_req_fifo_seq[(2**FIFO_ADDR_WIDTH)-1:0]; + +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] wr_req_fifo_wr_data; +reg [SEG_COUNT-1:0] wr_req_fifo_wr_eop; +reg [SEG_COUNT-1:0] wr_req_fifo_wr_valid; +reg [TX_SEQ_NUM_WIDTH-1:0] wr_req_fifo_wr_seq; +reg wr_req_fifo_we; + +reg wr_req_fifo_watermark_reg = 1'b0; +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] wr_req_fifo_rd_data_reg = 0, wr_req_fifo_rd_data_next; +reg [SEG_COUNT-1:0] wr_req_fifo_rd_eop_reg = 0, wr_req_fifo_rd_eop_next; +reg [SEG_COUNT-1:0] wr_req_fifo_rd_valid_reg = 0, wr_req_fifo_rd_valid_next; +reg [TX_SEQ_NUM_WIDTH-1:0] wr_req_fifo_rd_seq_reg = 0, wr_req_fifo_rd_seq_next; + +// completion FIFO +reg [FIFO_ADDR_WIDTH+1-1:0] cpl_fifo_wr_ptr_reg = 0; +reg [FIFO_ADDR_WIDTH+1-1:0] cpl_fifo_wr_ptr_cur_reg = 0; +reg [FIFO_ADDR_WIDTH+1-1:0] cpl_fifo_rd_ptr_reg = 0, cpl_fifo_rd_ptr_next; + +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] cpl_fifo_data[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT-1:0] cpl_fifo_eop[(2**FIFO_ADDR_WIDTH)-1:0]; +(* ramstyle = "no_rw_check, mlab" *) +reg [SEG_COUNT-1:0] cpl_fifo_valid[(2**FIFO_ADDR_WIDTH)-1:0]; + +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] cpl_fifo_wr_data; +reg [SEG_COUNT-1:0] cpl_fifo_wr_eop; +reg [SEG_COUNT-1:0] cpl_fifo_wr_valid; +reg cpl_fifo_we; + +reg cpl_fifo_watermark_reg = 1'b0; +reg [SEG_COUNT*SEG_DATA_WIDTH-1:0] cpl_fifo_rd_data_reg = 0, cpl_fifo_rd_data_next; +reg [SEG_COUNT-1:0] cpl_fifo_rd_eop_reg = 0, cpl_fifo_rd_eop_next; +reg [SEG_COUNT-1:0] cpl_fifo_rd_valid_reg = 0, cpl_fifo_rd_valid_next; + +// Read request processing +always @* begin + tx_rd_req_tlp_ready_next = 1'b0; + + rd_req_fifo_wr_data[31:0] = tx_rd_req_tlp_hdr[127:96]; + rd_req_fifo_wr_data[63:32] = tx_rd_req_tlp_hdr[95:64]; + rd_req_fifo_wr_data[95:64] = tx_rd_req_tlp_hdr[63:32]; + rd_req_fifo_wr_data[127:96] = tx_rd_req_tlp_hdr[31:0]; + rd_req_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:128] = 0; + rd_req_fifo_wr_seq = tx_rd_req_tlp_seq; + rd_req_fifo_we = 0; + + tx_rd_req_tlp_ready_next = !cpl_fifo_watermark_reg; + + if (tx_rd_req_tlp_valid && tx_rd_req_tlp_ready) begin + // send complete header (read request) + rd_req_fifo_we = 1; + end +end + +// Write request processing +always @* begin + wr_req_state_next = WR_REQ_STATE_IDLE; + + wr_req_payload_offset_next = wr_req_payload_offset_reg; + + wr_req_tlp_data_next = wr_req_tlp_data_reg; + wr_req_tlp_eop_next = wr_req_tlp_eop_reg; + + tx_wr_req_tlp_ready_next = 1'b0; + + if (wr_req_payload_offset_reg) begin + wr_req_fifo_wr_data = {tx_wr_req_tlp_data, wr_req_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-128]}; + end else begin + wr_req_fifo_wr_data = {tx_wr_req_tlp_data, wr_req_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-96]}; + end + wr_req_fifo_wr_eop = 0; + wr_req_fifo_wr_valid = 1; + wr_req_fifo_wr_seq = tx_wr_req_tlp_seq; + wr_req_fifo_we = 0; + + // combine header and payload, merge in read request TLPs + case (wr_req_state_reg) + WR_REQ_STATE_IDLE: begin + // idle state + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg; + + wr_req_payload_offset_next = tx_wr_req_tlp_hdr[125]; + + wr_req_fifo_wr_data[31:0] = tx_wr_req_tlp_hdr[127:96]; + wr_req_fifo_wr_data[63:32] = tx_wr_req_tlp_hdr[95:64]; + wr_req_fifo_wr_data[95:64] = tx_wr_req_tlp_hdr[63:32]; + if (wr_req_payload_offset_next) begin + wr_req_fifo_wr_data[127:96] = tx_rd_req_tlp_hdr[31:0]; + wr_req_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:128] = tx_wr_req_tlp_data; + end else begin + wr_req_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:96] = tx_wr_req_tlp_data; + end + wr_req_fifo_wr_eop = 0; + wr_req_fifo_wr_valid = 1; + wr_req_fifo_wr_seq = tx_wr_req_tlp_seq; + + if (tx_wr_req_tlp_valid && tx_wr_req_tlp_ready) begin + // send complete header and start of payload (completion) + wr_req_fifo_we = 1; + + wr_req_tlp_data_next = tx_wr_req_tlp_data; + wr_req_tlp_eop_next = tx_wr_req_tlp_eop; + + if (tx_wr_req_tlp_eop && wr_req_payload_offset_next && ((tx_wr_req_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-4)) == 0)) begin + wr_req_fifo_wr_eop = 1; + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg; + wr_req_state_next = WR_REQ_STATE_IDLE; + end else if (tx_wr_req_tlp_eop && !wr_req_payload_offset_next && ((tx_wr_req_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-3)) == 0)) begin + wr_req_fifo_wr_eop = 1; + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg; + wr_req_state_next = WR_REQ_STATE_IDLE; + end else begin + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg && !wr_req_tlp_eop_next; + wr_req_state_next = WR_REQ_STATE_PAYLOAD; + end + end else begin + wr_req_state_next = WR_REQ_STATE_IDLE; + end + end + WR_REQ_STATE_PAYLOAD: begin + // transfer payload (completion) + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg && !wr_req_tlp_eop_reg; + + if (wr_req_payload_offset_reg) begin + wr_req_fifo_wr_data = {tx_wr_req_tlp_data, wr_req_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-128]}; + end else begin + wr_req_fifo_wr_data = {tx_wr_req_tlp_data, wr_req_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-96]}; + end + wr_req_fifo_wr_eop = 0; + wr_req_fifo_wr_valid = 1; + wr_req_fifo_wr_seq = tx_wr_req_tlp_seq; + + if ((tx_wr_req_tlp_valid && tx_wr_req_tlp_ready) || (wr_req_tlp_eop_reg && !wr_req_fifo_watermark_reg)) begin + wr_req_fifo_we = 1; + + wr_req_tlp_data_next = tx_wr_req_tlp_data; + wr_req_tlp_eop_next = tx_wr_req_tlp_eop; + + if (wr_req_tlp_eop_reg || (tx_wr_req_tlp_eop && wr_req_payload_offset_reg && ((tx_wr_req_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-4)) == 0))) begin + wr_req_fifo_wr_eop = 1; + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg; + wr_req_state_next = WR_REQ_STATE_IDLE; + end else if (wr_req_tlp_eop_reg || (tx_wr_req_tlp_eop && !wr_req_payload_offset_reg && ((tx_wr_req_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-3)) == 0))) begin + wr_req_fifo_wr_eop = 1; + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg; + wr_req_state_next = WR_REQ_STATE_IDLE; + end else begin + tx_wr_req_tlp_ready_next = !wr_req_fifo_watermark_reg && !wr_req_tlp_eop_next; + wr_req_state_next = WR_REQ_STATE_PAYLOAD; + end + end else begin + wr_req_state_next = WR_REQ_STATE_PAYLOAD; + end + end + endcase +end + +// Completion processing +always @* begin + cpl_state_next = CPL_STATE_IDLE; + + cpl_tlp_data_next = cpl_tlp_data_reg; + cpl_tlp_eop_next = cpl_tlp_eop_reg; + + tx_cpl_tlp_ready_next = 1'b0; + + cpl_fifo_wr_data = {tx_cpl_tlp_data, cpl_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-96]}; + cpl_fifo_wr_eop = 0; + cpl_fifo_wr_valid = 1; + cpl_fifo_we = 0; + + // combine header and payload, merge in read request TLPs + case (cpl_state_reg) + CPL_STATE_IDLE: begin + // idle state + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg; + + cpl_fifo_wr_data[31:0] = tx_cpl_tlp_hdr[127:96]; + cpl_fifo_wr_data[63:32] = tx_cpl_tlp_hdr[95:64]; + cpl_fifo_wr_data[95:64] = tx_cpl_tlp_hdr[63:32]; + cpl_fifo_wr_data[SEG_COUNT*SEG_DATA_WIDTH-1:96] = tx_cpl_tlp_data; + cpl_fifo_wr_eop = 0; + cpl_fifo_wr_valid = 1; + + if (tx_cpl_tlp_valid && tx_cpl_tlp_ready) begin + // send complete header and start of payload (completion) + cpl_fifo_we = 1; + + cpl_tlp_data_next = tx_cpl_tlp_data; + cpl_tlp_eop_next = tx_cpl_tlp_eop; + + if (tx_cpl_tlp_eop && ((tx_cpl_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-3)) == 0)) begin + cpl_fifo_wr_eop = 1; + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg; + cpl_state_next = CPL_STATE_IDLE; + end else begin + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg && !cpl_tlp_eop_next; + cpl_state_next = CPL_STATE_PAYLOAD; + end + end else begin + cpl_state_next = CPL_STATE_IDLE; + end + end + CPL_STATE_PAYLOAD: begin + // transfer payload (completion) + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg && !cpl_tlp_eop_reg; + + cpl_fifo_wr_data = {tx_cpl_tlp_data, cpl_tlp_data_reg[TLP_DATA_WIDTH-1:TLP_DATA_WIDTH-96]}; + cpl_fifo_wr_eop = 0; + cpl_fifo_wr_valid = 1; + + if ((tx_cpl_tlp_valid && tx_cpl_tlp_ready) || (cpl_tlp_eop_reg && !cpl_fifo_watermark_reg)) begin + cpl_fifo_we = 1; + + cpl_tlp_data_next = tx_cpl_tlp_data; + cpl_tlp_eop_next = tx_cpl_tlp_eop; + + if (cpl_tlp_eop_reg || (tx_cpl_tlp_eop && ((tx_cpl_tlp_strb >> (TLP_DATA_WIDTH_DWORDS-3)) == 0))) begin + cpl_fifo_wr_eop = 1; + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg; + cpl_state_next = CPL_STATE_IDLE; + end else begin + tx_cpl_tlp_ready_next = !cpl_fifo_watermark_reg && !cpl_tlp_eop_next; + cpl_state_next = CPL_STATE_PAYLOAD; + end + end else begin + cpl_state_next = CPL_STATE_PAYLOAD; + end + end + endcase +end + +// Output arbitration +always @* begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + + m_axis_rd_req_tx_seq_num_next = 0; + m_axis_rd_req_tx_seq_num_valid_next = 0; + m_axis_wr_req_tx_seq_num_next = 0; + m_axis_wr_req_tx_seq_num_valid_next = 0; + + tx_st_data_next = 0; + tx_st_sop_next = 0; + tx_st_eop_next = 0; + tx_st_valid_next = 0; + + rd_req_fifo_rd_data_next = rd_req_fifo_rd_data_reg; + rd_req_fifo_rd_valid_next = rd_req_fifo_rd_valid_reg; + rd_req_fifo_rd_seq_next = rd_req_fifo_rd_seq_reg; + + wr_req_fifo_rd_data_next = wr_req_fifo_rd_data_reg; + wr_req_fifo_rd_eop_next = wr_req_fifo_rd_eop_reg; + wr_req_fifo_rd_valid_next = wr_req_fifo_rd_valid_reg; + wr_req_fifo_rd_seq_next = wr_req_fifo_rd_seq_reg; + + cpl_fifo_rd_data_next = cpl_fifo_rd_data_reg; + cpl_fifo_rd_eop_next = cpl_fifo_rd_eop_reg; + cpl_fifo_rd_valid_next = cpl_fifo_rd_valid_reg; + + // combine header and payload, merge in read request TLPs + case (tlp_output_state_reg) + TLP_OUTPUT_STATE_IDLE: begin + // idle state + + if (cpl_fifo_rd_valid_reg && tx_st_ready_delay_reg[1]) begin + // transfer completion + tx_st_data_next = cpl_fifo_rd_data_reg; + tx_st_sop_next = 1; + tx_st_eop_next = cpl_fifo_rd_eop_reg; + tx_st_valid_next = cpl_fifo_rd_valid_reg; + + cpl_fifo_rd_valid_next = 0; + + if (cpl_fifo_rd_eop_reg) begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_CPL_PAYLOAD; + end + end else if (rd_req_fifo_rd_valid_reg && tx_st_ready_delay_reg[1]) begin + // transfer read request + tx_st_data_next = rd_req_fifo_rd_data_reg; + tx_st_sop_next = 1; + tx_st_eop_next = 1; + tx_st_valid_next = 1; + + rd_req_fifo_rd_valid_next = 0; + + // return read request sequence number + m_axis_rd_req_tx_seq_num_next = rd_req_fifo_rd_seq_reg; + m_axis_rd_req_tx_seq_num_valid_next = 1'b1; + end else if (wr_req_fifo_rd_valid_reg && tx_st_ready_delay_reg[1]) begin + // transfer write request + tx_st_data_next = wr_req_fifo_rd_data_reg; + tx_st_sop_next = 1; + tx_st_eop_next = wr_req_fifo_rd_eop_reg; + tx_st_valid_next = wr_req_fifo_rd_valid_reg; + + wr_req_fifo_rd_valid_next = 0; + + // return write request sequence number + m_axis_wr_req_tx_seq_num_next = wr_req_fifo_rd_seq_reg; + m_axis_wr_req_tx_seq_num_valid_next = 1'b1; + + if (wr_req_fifo_rd_eop_reg) begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_WR_PAYLOAD; + end + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + end + end + TLP_OUTPUT_STATE_WR_PAYLOAD: begin + // transfer payload (write request) + tx_st_data_next = wr_req_fifo_rd_data_reg; + tx_st_sop_next = 0; + tx_st_eop_next = wr_req_fifo_rd_eop_reg; + + if (wr_req_fifo_rd_valid_reg && tx_st_ready_delay_reg[1]) begin + tx_st_valid_next = wr_req_fifo_rd_valid_reg; + + wr_req_fifo_rd_valid_next = 0; + + if (wr_req_fifo_rd_eop_reg) begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_WR_PAYLOAD; + end + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_WR_PAYLOAD; + end + end + TLP_OUTPUT_STATE_CPL_PAYLOAD: begin + // transfer payload (completion) + tx_st_data_next = cpl_fifo_rd_data_reg; + tx_st_sop_next = 0; + tx_st_eop_next = cpl_fifo_rd_eop_reg; + + if (cpl_fifo_rd_valid_reg && tx_st_ready_delay_reg[1]) begin + tx_st_valid_next = cpl_fifo_rd_valid_reg; + + cpl_fifo_rd_valid_next = 0; + + if (cpl_fifo_rd_eop_reg) begin + tlp_output_state_next = TLP_OUTPUT_STATE_IDLE; + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_CPL_PAYLOAD; + end + end else begin + tlp_output_state_next = TLP_OUTPUT_STATE_CPL_PAYLOAD; + end + end + endcase + + rd_req_fifo_rd_ptr_next = rd_req_fifo_rd_ptr_reg; + + if (!rd_req_fifo_rd_valid_next && rd_req_fifo_rd_ptr_reg != rd_req_fifo_wr_ptr_reg) begin + // read request FIFO not empty + rd_req_fifo_rd_data_next = rd_req_fifo_data[rd_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + rd_req_fifo_rd_valid_next = 1; + rd_req_fifo_rd_seq_next = rd_req_fifo_seq[rd_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + rd_req_fifo_rd_ptr_next = rd_req_fifo_rd_ptr_reg + 1; + end + + wr_req_fifo_rd_ptr_next = wr_req_fifo_rd_ptr_reg; + + if (!wr_req_fifo_rd_valid_next && wr_req_fifo_rd_ptr_reg != wr_req_fifo_wr_ptr_reg) begin + // write request FIFO not empty + wr_req_fifo_rd_data_next = wr_req_fifo_data[wr_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + wr_req_fifo_rd_eop_next = wr_req_fifo_eop[wr_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + wr_req_fifo_rd_valid_next = wr_req_fifo_valid[wr_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + wr_req_fifo_rd_seq_next = wr_req_fifo_seq[wr_req_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + wr_req_fifo_rd_ptr_next = wr_req_fifo_rd_ptr_reg + 1; + end + + cpl_fifo_rd_ptr_next = cpl_fifo_rd_ptr_reg; + + if (!cpl_fifo_rd_valid_next && cpl_fifo_rd_ptr_reg != cpl_fifo_wr_ptr_reg) begin + // completion FIFO not empty + cpl_fifo_rd_data_next = cpl_fifo_data[cpl_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + cpl_fifo_rd_eop_next = cpl_fifo_eop[cpl_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + cpl_fifo_rd_valid_next = cpl_fifo_valid[cpl_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]]; + cpl_fifo_rd_ptr_next = cpl_fifo_rd_ptr_reg + 1; + end +end + +always @(posedge clk) begin + wr_req_state_reg <= wr_req_state_next; + cpl_state_reg <= cpl_state_next; + tlp_output_state_reg <= tlp_output_state_next; + + wr_req_payload_offset_reg <= wr_req_payload_offset_next; + + wr_req_tlp_data_reg <= wr_req_tlp_data_next; + wr_req_tlp_eop_reg <= wr_req_tlp_eop_next; + + cpl_tlp_data_reg <= cpl_tlp_data_next; + cpl_tlp_eop_reg <= cpl_tlp_eop_next; + + tx_rd_req_tlp_ready_reg <= tx_rd_req_tlp_ready_next; + tx_wr_req_tlp_ready_reg <= tx_wr_req_tlp_ready_next; + tx_cpl_tlp_ready_reg <= tx_cpl_tlp_ready_next; + + m_axis_rd_req_tx_seq_num_reg <= m_axis_rd_req_tx_seq_num_next; + m_axis_rd_req_tx_seq_num_valid_reg <= m_axis_rd_req_tx_seq_num_valid_next; + m_axis_wr_req_tx_seq_num_reg <= m_axis_wr_req_tx_seq_num_next; + m_axis_wr_req_tx_seq_num_valid_reg <= m_axis_wr_req_tx_seq_num_valid_next; + + tx_st_data_reg <= tx_st_data_next; + tx_st_sop_reg <= tx_st_sop_next; + tx_st_eop_reg <= tx_st_eop_next; + tx_st_valid_reg <= tx_st_valid_next; + + tx_st_ready_delay_reg <= {tx_st_ready_delay_reg, tx_st_ready}; + + if (rd_req_fifo_we) begin + rd_req_fifo_data[rd_req_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH-1:0]] <= rd_req_fifo_wr_data; + rd_req_fifo_seq[rd_req_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH-1:0]] <= rd_req_fifo_wr_seq; + rd_req_fifo_wr_ptr_reg <= rd_req_fifo_wr_ptr_reg + 1; + end + rd_req_fifo_rd_ptr_reg <= rd_req_fifo_rd_ptr_next; + + rd_req_fifo_rd_data_reg <= rd_req_fifo_rd_data_next; + rd_req_fifo_rd_valid_reg <= rd_req_fifo_rd_valid_next; + rd_req_fifo_rd_seq_reg <= rd_req_fifo_rd_seq_next; + + rd_req_fifo_watermark_reg <= $unsigned(rd_req_fifo_wr_ptr_reg - rd_req_fifo_rd_ptr_reg) >= 2**FIFO_ADDR_WIDTH-4; + + if (wr_req_fifo_we) begin + wr_req_fifo_data[wr_req_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= wr_req_fifo_wr_data; + wr_req_fifo_eop[wr_req_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= wr_req_fifo_wr_eop; + wr_req_fifo_valid[wr_req_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= wr_req_fifo_wr_valid; + wr_req_fifo_seq[wr_req_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= wr_req_fifo_wr_seq; + wr_req_fifo_wr_ptr_cur_reg <= wr_req_fifo_wr_ptr_cur_reg + 1; + if (wr_req_fifo_wr_eop) begin + // update write pointer at end of frame + wr_req_fifo_wr_ptr_reg <= wr_req_fifo_wr_ptr_cur_reg + 1; + end + end + wr_req_fifo_rd_ptr_reg <= wr_req_fifo_rd_ptr_next; + + wr_req_fifo_rd_data_reg <= wr_req_fifo_rd_data_next; + wr_req_fifo_rd_eop_reg <= wr_req_fifo_rd_eop_next; + wr_req_fifo_rd_valid_reg <= wr_req_fifo_rd_valid_next; + wr_req_fifo_rd_seq_reg <= wr_req_fifo_rd_seq_next; + + wr_req_fifo_watermark_reg <= $unsigned(wr_req_fifo_wr_ptr_cur_reg - wr_req_fifo_rd_ptr_reg) >= 2**FIFO_ADDR_WIDTH-4; + + if (cpl_fifo_we) begin + cpl_fifo_data[cpl_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= cpl_fifo_wr_data; + cpl_fifo_eop[cpl_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= cpl_fifo_wr_eop; + cpl_fifo_valid[cpl_fifo_wr_ptr_cur_reg[FIFO_ADDR_WIDTH-1:0]] <= cpl_fifo_wr_valid; + cpl_fifo_wr_ptr_cur_reg <= cpl_fifo_wr_ptr_cur_reg + 1; + if (cpl_fifo_wr_eop) begin + // update write pointer at end of frame + cpl_fifo_wr_ptr_reg <= cpl_fifo_wr_ptr_cur_reg + 1; + end + end + cpl_fifo_rd_ptr_reg <= cpl_fifo_rd_ptr_next; + + cpl_fifo_rd_data_reg <= cpl_fifo_rd_data_next; + cpl_fifo_rd_eop_reg <= cpl_fifo_rd_eop_next; + cpl_fifo_rd_valid_reg <= cpl_fifo_rd_valid_next; + + cpl_fifo_watermark_reg <= $unsigned(cpl_fifo_wr_ptr_cur_reg - cpl_fifo_rd_ptr_reg) >= 2**FIFO_ADDR_WIDTH-4; + + if (rst) begin + wr_req_state_reg <= WR_REQ_STATE_IDLE; + cpl_state_reg <= CPL_STATE_IDLE; + tlp_output_state_reg <= TLP_OUTPUT_STATE_IDLE; + + tx_rd_req_tlp_ready_reg <= 1'b0; + tx_wr_req_tlp_ready_reg <= 1'b0; + tx_cpl_tlp_ready_reg <= 1'b0; + + m_axis_rd_req_tx_seq_num_valid_reg <= 0; + m_axis_wr_req_tx_seq_num_valid_reg <= 0; + + tx_st_valid_reg <= 0; + tx_st_ready_delay_reg <= 0; + + rd_req_fifo_wr_ptr_reg <= 0; + rd_req_fifo_rd_ptr_reg <= 0; + rd_req_fifo_rd_valid_reg <= 1'b0; + + wr_req_fifo_wr_ptr_reg <= 0; + wr_req_fifo_wr_ptr_cur_reg <= 0; + wr_req_fifo_rd_ptr_reg <= 0; + wr_req_fifo_rd_valid_reg <= 0; + + cpl_fifo_wr_ptr_reg <= 0; + cpl_fifo_wr_ptr_cur_reg <= 0; + cpl_fifo_rd_ptr_reg <= 0; + cpl_fifo_rd_valid_reg <= 0; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/rtl/pcie_s10_msi.v b/fpga/lib/pcie/rtl/pcie_s10_msi.v new file mode 100644 index 000000000..2fc215f0b --- /dev/null +++ b/fpga/lib/pcie/rtl/pcie_s10_msi.v @@ -0,0 +1,149 @@ +/* + +Copyright (c) 2021 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 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Intel Stratix 10 H-Tile/L-Tile PCIe MSI shim + */ +module pcie_s10_msi # +( + parameter MSI_COUNT = 32 +) +( + input wire clk, + input wire rst, + + /* + * Interrupt request inputs + */ + input wire [MSI_COUNT-1:0] msi_irq, + + /* + * Interface to H-Tile/L-Tile PCIe IP core + */ + output wire app_msi_req, + input wire app_msi_ack, + output wire [2:0] app_msi_tc, + output wire [4:0] app_msi_num, + output wire [1:0] app_msi_func_num, + + /* + * Configuration + */ + input wire cfg_msi_enable, + input wire [2:0] cfg_multiple_msi_enable, + input wire [31:0] cfg_msi_mask +); + +reg active_reg = 1'b0, active_next; + +reg [MSI_COUNT-1:0] msi_irq_reg = {MSI_COUNT{1'b0}}; +reg [MSI_COUNT-1:0] msi_irq_last_reg = {MSI_COUNT{1'b0}}; +reg [MSI_COUNT-1:0] msi_irq_active_reg = {MSI_COUNT{1'b0}}, msi_irq_active_next; + +reg [MSI_COUNT-1:0] msi_irq_mask_reg = {MSI_COUNT{1'b0}}, msi_irq_mask_next; + +reg [4:0] msi_int_reg = 0, msi_int_next; + +assign app_msi_req = active_reg; +assign app_msi_tc = 0; // TC 0 +assign app_msi_num = msi_int_reg; +assign app_msi_func_num = 0; // PF 0 + +wire [MSI_COUNT-1:0] message_enable_mask = cfg_multiple_msi_enable > 3'd4 ? {32{1'b1}} : {32{1'b1}} >> (32 - (1 << cfg_multiple_msi_enable)); + +reg [MSI_COUNT-1:0] acknowledge; +wire [MSI_COUNT-1:0] grant; +wire [4:0] grant_encoded; +wire grant_valid; + +// arbiter instance +arbiter #( + .PORTS(MSI_COUNT), + .ARB_TYPE_ROUND_ROBIN(1), + .ARB_BLOCK(1), + .ARB_BLOCK_ACK(1), + .ARB_LSB_HIGH_PRIORITY(1) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(msi_irq_active_reg & msi_irq_mask_reg & ~grant), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +always @* begin + active_next = active_reg; + + msi_irq_active_next = (msi_irq_active_reg | (msi_irq_reg & ~msi_irq_last_reg)); + + msi_irq_mask_next = ~cfg_msi_mask & message_enable_mask & {32{cfg_msi_enable}}; + + msi_int_next = msi_int_reg; + + acknowledge = {MSI_COUNT{1'b0}}; + + if (!active_reg) begin + if (cfg_msi_enable && grant_valid) begin + msi_int_next = grant_encoded; + active_next = 1'b1; + end + end else begin + if (app_msi_ack) begin + msi_irq_active_next = msi_irq_active_next & ~grant; + acknowledge = grant; + active_next = 1'b0; + end + end +end + +always @(posedge clk) begin + active_reg <= active_next; + msi_irq_reg <= msi_irq; + msi_irq_last_reg <= msi_irq_reg; + msi_irq_active_reg <= msi_irq_active_next; + msi_irq_mask_reg <= msi_irq_mask_next; + msi_int_reg <= msi_int_next; + + if (rst) begin + active_reg <= 1'b0; + msi_irq_reg <= {MSI_COUNT{1'b0}}; + msi_irq_last_reg <= {MSI_COUNT{1'b0}}; + msi_irq_active_reg <= {MSI_COUNT{1'b0}}; + msi_irq_mask_reg <= {MSI_COUNT{1'b0}}; + msi_int_reg <= {MSI_COUNT{1'b0}}; + end +end + +endmodule + +`resetall diff --git a/fpga/lib/pcie/rtl/pcie_us_axi_dma_rd.v b/fpga/lib/pcie/rtl/pcie_us_axi_dma_rd.v index d293bc994..5752fa44a 100644 --- a/fpga/lib/pcie/rtl/pcie_us_axi_dma_rd.v +++ b/fpga/lib/pcie/rtl/pcie_us_axi_dma_rd.v @@ -359,6 +359,7 @@ reg [LEN_WIDTH-1:0] req_op_count_reg = {LEN_WIDTH{1'b0}}, req_op_count_next; reg [12:0] req_tlp_count_reg = 13'd0, req_tlp_count_next; reg req_zero_len_reg = 1'b0, req_zero_len_next; reg [OP_TAG_WIDTH-1:0] req_op_tag_reg = {OP_TAG_WIDTH{1'b0}}, req_op_tag_next; +reg req_op_tag_valid_reg = 1'b0, req_op_tag_valid_next; reg [PCIE_TAG_WIDTH-1:0] req_pcie_tag_reg = {PCIE_TAG_WIDTH{1'b0}}, req_pcie_tag_next; reg req_pcie_tag_valid_reg = 1'b0, req_pcie_tag_valid_next; @@ -395,9 +396,13 @@ reg have_credit_reg = 1'b0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_wr_ptr_reg = 0; reg [STATUS_FIFO_ADDR_WIDTH+1-1:0] status_fifo_rd_ptr_reg = 0, status_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] status_fifo_op_tag[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg status_fifo_skip[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg status_fifo_finish[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] status_fifo_error[(2**STATUS_FIFO_ADDR_WIDTH)-1:0]; reg [OP_TAG_WIDTH-1:0] status_fifo_wr_op_tag; reg status_fifo_wr_skip; @@ -484,21 +489,28 @@ reg pcie_tag_table_start_en_reg = 1'b0, pcie_tag_table_start_en_next; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_table_finish_ptr; reg pcie_tag_table_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [AXI_ADDR_WIDTH-1:0] pcie_tag_table_axi_addr[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] pcie_tag_table_op_tag[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_zero_len[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_a[(2**PCIE_TAG_WIDTH)-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg pcie_tag_table_active_b[(2**PCIE_TAG_WIDTH)-1:0]; reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_wr_tag; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_1+1-1:0] pcie_tag_fifo_1_rd_ptr_reg = 0, pcie_tag_fifo_1_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH_1-1:0] pcie_tag_fifo_1_mem [2**PCIE_TAG_WIDTH_1-1:0]; reg pcie_tag_fifo_1_we; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_wr_ptr_reg = 0; reg [PCIE_TAG_WIDTH_2+1-1:0] pcie_tag_fifo_2_rd_ptr_reg = 0, pcie_tag_fifo_2_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_TAG_WIDTH-1:0] pcie_tag_fifo_2_mem [2**PCIE_TAG_WIDTH_2-1:0]; reg pcie_tag_fifo_2_we; @@ -515,19 +527,30 @@ reg op_table_update_status_en; reg [OP_TAG_WIDTH-1:0] op_table_read_finish_ptr; reg op_table_read_finish_en; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_init_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_commit [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_read_error [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_start [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TABLE_READ_COUNT_WIDTH-1:0] op_table_read_count_finish [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_a [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_error_b [2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [3:0] op_table_error_code [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_wr_ptr_reg = 0; reg [OP_TAG_WIDTH+1-1:0] op_tag_fifo_rd_ptr_reg = 0, op_tag_fifo_rd_ptr_next; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OP_TAG_WIDTH-1:0] op_tag_fifo_mem [2**OP_TAG_WIDTH-1:0]; reg [OP_TAG_WIDTH-1:0] op_tag_fifo_wr_tag; reg op_tag_fifo_we; @@ -567,12 +590,13 @@ always @* begin req_tlp_count_next = req_tlp_count_reg; req_zero_len_next = req_zero_len_reg; req_op_tag_next = req_op_tag_reg; + req_op_tag_valid_next = req_op_tag_valid_reg; req_pcie_tag_next = req_pcie_tag_reg; req_pcie_tag_valid_next = req_pcie_tag_valid_reg; inc_active_tx = 1'b0; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b0; @@ -580,8 +604,6 @@ always @* begin op_table_read_start_commit = 1'b0; op_table_read_start_en = 1'b0; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; - // TLP size computation if (req_op_count_reg + req_pcie_addr_reg[1:0] <= {max_read_request_size_dw_reg, 2'b00}) begin // packet smaller than max read request size @@ -705,7 +727,7 @@ always @* begin // TLP segmentation and request generation case (req_state_reg) REQ_STATE_IDLE: begin - s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); + s_axis_read_desc_ready_next = init_done_reg && enable && req_op_tag_valid_reg; if (s_axis_read_desc_ready && s_axis_read_desc_valid) begin s_axis_read_desc_ready_next = 1'b0; @@ -719,11 +741,9 @@ always @* begin req_op_count_next = s_axis_read_desc_len; req_zero_len_next = 1'b0; end - req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; - op_table_start_ptr = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + op_table_start_ptr = req_op_tag_reg; op_table_start_tag = s_axis_read_desc_tag; op_table_start_en = 1'b1; - op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg+1; req_state_next = REQ_STATE_START; end else begin req_state_next = REQ_STATE_IDLE; @@ -756,6 +776,7 @@ always @* begin if (!req_last_tlp) begin req_state_next = REQ_STATE_START; end else begin + req_op_tag_valid_next = 1'b0; s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); req_state_next = REQ_STATE_IDLE; end @@ -794,6 +815,7 @@ always @* begin if (!req_last_tlp) begin req_state_next = REQ_STATE_START; end else begin + req_op_tag_valid_next = 1'b0; s_axis_read_desc_ready_next = init_done_reg && enable && (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg); req_state_next = REQ_STATE_IDLE; end @@ -804,6 +826,16 @@ always @* begin end endcase + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg; + + if (!req_op_tag_valid_next) begin + if (op_tag_fifo_rd_ptr_reg != op_tag_fifo_wr_ptr_reg) begin + req_op_tag_next = op_tag_fifo_mem[op_tag_fifo_rd_ptr_reg[OP_TAG_WIDTH-1:0]]; + req_op_tag_valid_next = 1'b1; + op_tag_fifo_rd_ptr_next = op_tag_fifo_rd_ptr_reg + 1; + end + end + pcie_tag_fifo_1_rd_ptr_next = pcie_tag_fifo_1_rd_ptr_reg; pcie_tag_fifo_2_rd_ptr_next = pcie_tag_fifo_2_rd_ptr_reg; @@ -1474,6 +1506,7 @@ always @(posedge clk) begin req_tlp_count_reg <= req_tlp_count_next; req_zero_len_reg <= req_zero_len_next; req_op_tag_reg <= req_op_tag_next; + req_op_tag_valid_reg <= req_op_tag_valid_next; req_pcie_tag_reg <= req_pcie_tag_next; req_pcie_tag_valid_reg <= req_pcie_tag_valid_next; @@ -1644,6 +1677,7 @@ always @(posedge clk) begin init_pcie_tag_reg <= 1'b1; init_op_tag_reg <= 1'b1; + req_op_tag_valid_reg <= 1'b0; req_pcie_tag_valid_reg <= 1'b0; finish_tag_reg <= 1'b0; diff --git a/fpga/lib/pcie/rtl/pcie_us_axi_dma_wr.v b/fpga/lib/pcie/rtl/pcie_us_axi_dma_wr.v index 83eb7f3e2..d23c80427 100644 --- a/fpga/lib/pcie/rtl/pcie_us_axi_dma_wr.v +++ b/fpga/lib/pcie/rtl/pcie_us_axi_dma_wr.v @@ -411,16 +411,27 @@ reg op_table_finish_en; reg [2**OP_TAG_WIDTH-1:0] op_table_active = 0; reg [2**OP_TAG_WIDTH-1:0] op_table_tx_done = 0; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [PCIE_ADDR_WIDTH-1:0] op_table_pcie_addr[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [11:0] op_table_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_zero_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [9:0] op_table_dword_len[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_input_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [CYCLE_COUNT_WIDTH-1:0] op_table_output_cycle_count[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [OFFSET_WIDTH-1:0] op_table_offset[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_bubble_cycle[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [TAG_WIDTH-1:0] op_table_tag[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg op_table_last[2**OP_TAG_WIDTH-1:0]; +(* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) reg [1:0] op_table_resp[2**OP_TAG_WIDTH-1:0]; integer i; diff --git a/fpga/lib/pcie/tb/pcie_if.py b/fpga/lib/pcie/tb/pcie_if.py index c6c456a7f..e02573e7e 100644 --- a/fpga/lib/pcie/tb/pcie_if.py +++ b/fpga/lib/pcie/tb/pcie_if.py @@ -127,8 +127,9 @@ class PcieIfFrame: hdr = tlp.pack_header() # force 64-bit address - if tlp.fmt_type in {TlpType.MEM_READ, TlpType.MEM_READ_LOCKED, TlpType.MEM_WRITE, - TlpType.IO_READ, TlpType.IO_WRITE, TlpType.FETCH_ADD, TlpType.SWAP, TlpType.CAS}: + if force_64bit_addr and tlp.fmt_type in {TlpType.MEM_READ, TlpType.MEM_READ_LOCKED, + TlpType.MEM_WRITE, TlpType.IO_READ, TlpType.IO_WRITE, TlpType.FETCH_ADD, + TlpType.SWAP, TlpType.CAS}: hdr = bytes([hdr[0] | 0x20]) + hdr[1:8] + b'\x00'*4 + hdr[8:12] diff --git a/fpga/lib/pcie/tb/pcie_s10_if/Makefile b/fpga/lib/pcie/tb/pcie_s10_if/Makefile new file mode 100644 index 000000000..5430715e5 --- /dev/null +++ b/fpga/lib/pcie/tb/pcie_s10_if/Makefile @@ -0,0 +1,118 @@ +# Copyright (c) 2021 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 = pcie_s10_if +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/$(DUT)_rx.v +VERILOG_SOURCES += ../../rtl/$(DUT)_tx.v +VERILOG_SOURCES += ../../rtl/pcie_s10_cfg.v +VERILOG_SOURCES += ../../rtl/pcie_s10_msi.v +VERILOG_SOURCES += ../../rtl/arbiter.v +VERILOG_SOURCES += ../../rtl/priority_encoder.v + +# module parameters +export PARAM_SEG_COUNT ?= 1 +export PARAM_SEG_DATA_WIDTH ?= 256 +export PARAM_SEG_EMPTY_WIDTH ?= $(shell python -c "print((($(PARAM_SEG_DATA_WIDTH)//32)-1).bit_length())" ) +export PARAM_TLP_SEG_COUNT ?= 1 +export PARAM_TLP_SEG_DATA_WIDTH ?= $(shell expr $(PARAM_SEG_COUNT) \* $(PARAM_SEG_DATA_WIDTH) / $(PARAM_TLP_SEG_COUNT) ) +export PARAM_TLP_SEG_STRB_WIDTH ?= $(shell expr $(PARAM_TLP_SEG_DATA_WIDTH) / 32 ) +export PARAM_TLP_SEG_HDR_WIDTH ?= 128 +export PARAM_TX_SEQ_NUM_WIDTH ?= 6 +export PARAM_L_TILE ?= 0 +export PARAM_PF_COUNT ?= 1 +export PARAM_VF_COUNT ?= 0 +export PARAM_F_COUNT ?= $(shell expr $(PARAM_PF_COUNT) + $(PARAM_VF_COUNT) ) +export PARAM_IO_BAR_INDEX ?= 3 +export PARAM_MSI_ENABLE ?= 1 +export PARAM_MSI_COUNT ?= 32 + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).SEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_COUNT=$(PARAM_TLP_SEG_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_DATA_WIDTH=$(PARAM_TLP_SEG_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_STRB_WIDTH=$(PARAM_TLP_SEG_STRB_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TLP_SEG_HDR_WIDTH=$(PARAM_TLP_SEG_HDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_COUNT=$(PARAM_TX_SEQ_NUM_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).L_TILE=$(PARAM_L_TILE) + COMPILE_ARGS += -P $(TOPLEVEL).PF_COUNT=$(PARAM_PF_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).VF_COUNT=$(PARAM_VF_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).F_COUNT=$(PARAM_F_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).IO_BAR_INDEX=$(PARAM_IO_BAR_INDEX) + COMPILE_ARGS += -P $(TOPLEVEL).MSI_ENABLE=$(PARAM_MSI_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).MSI_COUNT=$(PARAM_MSI_COUNT) + + 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 += -GSEG_COUNT=$(PARAM_SEG_COUNT) + COMPILE_ARGS += -GSEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH) + COMPILE_ARGS += -GSEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH) + COMPILE_ARGS += -GTLP_SEG_COUNT=$(PARAM_TLP_SEG_COUNT) + COMPILE_ARGS += -GTLP_SEG_DATA_WIDTH=$(PARAM_TLP_SEG_DATA_WIDTH) + COMPILE_ARGS += -GTLP_SEG_STRB_WIDTH=$(PARAM_TLP_SEG_STRB_WIDTH) + COMPILE_ARGS += -GTLP_SEG_HDR_WIDTH=$(PARAM_TLP_SEG_HDR_WIDTH) + COMPILE_ARGS += -GTX_SEQ_NUM_COUNT=$(PARAM_TX_SEQ_NUM_COUNT) + COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GL_TILE=$(PARAM_L_TILE) + COMPILE_ARGS += -GPF_COUNT=$(PARAM_PF_COUNT) + COMPILE_ARGS += -GVF_COUNT=$(PARAM_VF_COUNT) + COMPILE_ARGS += -GF_COUNT=$(PARAM_F_COUNT) + COMPILE_ARGS += -GIO_BAR_INDEX=$(PARAM_IO_BAR_INDEX) + COMPILE_ARGS += -GMSI_ENABLE=$(PARAM_MSI_ENABLE) + COMPILE_ARGS += -GMSI_COUNT=$(PARAM_MSI_COUNT) + + 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 diff --git a/fpga/lib/pcie/tb/pcie_s10_if/pcie_if.py b/fpga/lib/pcie/tb/pcie_s10_if/pcie_if.py new file mode 120000 index 000000000..10502b03d --- /dev/null +++ b/fpga/lib/pcie/tb/pcie_s10_if/pcie_if.py @@ -0,0 +1 @@ +../pcie_if.py \ No newline at end of file diff --git a/fpga/lib/pcie/tb/pcie_s10_if/test_pcie_s10_if.py b/fpga/lib/pcie/tb/pcie_s10_if/test_pcie_s10_if.py new file mode 100644 index 000000000..42fa3932c --- /dev/null +++ b/fpga/lib/pcie/tb/pcie_s10_if/test_pcie_s10_if.py @@ -0,0 +1,517 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2021 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 itertools +import logging +import os +import sys + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.triggers import RisingEdge, FallingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus + +try: + from pcie_if import PcieIfTestDevice, PcieIfRxBus, PcieIfTxBus +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + from pcie_if import PcieIfTestDevice, PcieIfRxBus, PcieIfTxBus + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = S10PcieDevice( + # configuration options + pcie_generation=3, + # pcie_link_width=2, + # pld_clk_frequency=250e6, + l_tile=False, + + # signals + # Clock and reset + # npor=dut.npor, + # pin_perst=dut.pin_perst, + # ninit_done=dut.ninit_done, + # pld_clk_inuse=dut.pld_clk_inuse, + # pld_core_ready=dut.pld_core_ready, + reset_status=dut.rst, + # clr_st=dut.clr_st, + # refclk=dut.refclk, + coreclkout_hip=dut.clk, + + # RX interface + rx_bus=S10RxBus.from_prefix(dut, "rx_st"), + + # TX interface + tx_bus=S10TxBus.from_prefix(dut, "tx_st"), + + # TX flow control + tx_ph_cdts=dut.tx_ph_cdts, + tx_pd_cdts=dut.tx_pd_cdts, + tx_nph_cdts=dut.tx_nph_cdts, + tx_npd_cdts=dut.tx_npd_cdts, + tx_cplh_cdts=dut.tx_cplh_cdts, + tx_cpld_cdts=dut.tx_cpld_cdts, + tx_hdr_cdts_consumed=dut.tx_hdr_cdts_consumed, + tx_data_cdts_consumed=dut.tx_data_cdts_consumed, + tx_cdts_type=dut.tx_cdts_type, + tx_cdts_data_value=dut.tx_cdts_data_value, + + # Hard IP status + # int_status=dut.int_status, + # int_status_common=dut.int_status_common, + # derr_cor_ext_rpl=dut.derr_cor_ext_rpl, + # derr_rpl=dut.derr_rpl, + # derr_cor_ext_rcv=dut.derr_cor_ext_rcv, + # derr_uncor_ext_rcv=dut.derr_uncor_ext_rcv, + # rx_par_err=dut.rx_par_err, + # tx_par_err=dut.tx_par_err, + # ltssmstate=dut.ltssmstate, + # link_up=dut.link_up, + # lane_act=dut.lane_act, + # currentspeed=dut.currentspeed, + + # Power management + # pm_linkst_in_l1=dut.pm_linkst_in_l1, + # pm_linkst_in_l0s=dut.pm_linkst_in_l0s, + # pm_state=dut.pm_state, + # pm_dstate=dut.pm_dstate, + # apps_pm_xmt_pme=dut.apps_pm_xmt_pme, + # apps_ready_entr_l23=dut.apps_ready_entr_l23, + # apps_pm_xmt_turnoff=dut.apps_pm_xmt_turnoff, + # app_init_rst=dut.app_init_rst, + # app_xfer_pending=dut.app_xfer_pending, + + # Interrupt interface + app_msi_req=dut.app_msi_req, + app_msi_ack=dut.app_msi_ack, + app_msi_tc=dut.app_msi_tc, + app_msi_num=dut.app_msi_num, + app_msi_func_num=dut.app_msi_func_num, + # app_int_sts=dut.app_int_sts, + + # Error interface + # serr_out=dut.serr_out, + # hip_enter_err_mode=dut.hip_enter_err_mode, + # app_err_valid=dut.app_err_valid, + # app_err_hdr=dut.app_err_hdr, + # app_err_info=dut.app_err_info, + # app_err_func_num=dut.app_err_func_num, + + # Configuration output + tl_cfg_func=dut.tl_cfg_func, + tl_cfg_add=dut.tl_cfg_add, + tl_cfg_ctl=dut.tl_cfg_ctl, + + # Configuration extension bus + # ceb_req=dut.ceb_req, + # ceb_ack=dut.ceb_ack, + # ceb_addr=dut.ceb_addr, + # ceb_din=dut.ceb_din, + # ceb_dout=dut.ceb_dout, + # ceb_wr=dut.ceb_wr, + # ceb_cdm_convert_data=dut.ceb_cdm_convert_data, + # ceb_func_num=dut.ceb_func_num, + # ceb_vf_num=dut.ceb_vf_num, + # ceb_vf_active=dut.ceb_vf_active, + + # Hard IP reconfiguration interface + # hip_reconfig_clk=dut.hip_reconfig_clk, + # hip_reconfig_address=dut.hip_reconfig_address, + # hip_reconfig_read=dut.hip_reconfig_read, + # hip_reconfig_readdata=dut.hip_reconfig_readdata, + # hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid, + # hip_reconfig_write=dut.hip_reconfig_write, + # hip_reconfig_writedata=dut.hip_reconfig_writedata, + # hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest, + ) + + self.test_dev = PcieIfTestDevice( + clk=dut.clk, + rst=dut.rst, + + rx_req_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_req_tlp"), + + tx_cpl_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_cpl_tlp"), + + tx_rd_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_rd_req_tlp"), + rd_req_tx_seq_num=dut.m_axis_rd_req_tx_seq_num, + rd_req_tx_seq_num_valid=dut.m_axis_rd_req_tx_seq_num_valid, + + tx_wr_req_tlp_bus=PcieIfTxBus.from_prefix(dut, "tx_wr_req_tlp"), + wr_req_tx_seq_num=dut.m_axis_wr_req_tx_seq_num, + wr_req_tx_seq_num_valid=dut.m_axis_wr_req_tx_seq_num_valid, + + rx_cpl_tlp_bus=PcieIfRxBus.from_prefix(dut, "rx_cpl_tlp"), + ) + + self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 1024*1024) + self.test_dev.add_mem_region(1024*1024) + self.dev.functions[0].configure_bar(1, 1024*1024, True, True) + self.test_dev.add_prefetchable_mem_region(1024*1024) + self.dev.functions[0].configure_bar(3, 1024, False, False, True) + self.test_dev.add_io_region(1024) + + self.dut.msi_irq.setimmediatevalue(0) + + def set_idle_generator(self, generator=None): + if generator: + self.dev.rx_source.set_pause_generator(generator()) + self.test_dev.tx_cpl_tlp_source.set_pause_generator(generator()) + self.test_dev.tx_rd_req_tlp_source.set_pause_generator(generator()) + self.test_dev.tx_wr_req_tlp_source.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.dev.tx_sink.set_pause_generator(generator()) + self.test_dev.rx_req_tlp_sink.set_pause_generator(generator()) + self.test_dev.rx_cpl_tlp_sink.set_pause_generator(generator()) + + +async def run_test_mem(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + await FallingEdge(dut.rst) + await Timer(100, 'ns') + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + tb.test_dev.dev_max_payload = tb.dev.functions[0].pcie_cap.max_payload_size + tb.test_dev.dev_max_read_req = tb.dev.functions[0].pcie_cap.max_read_request_size + tb.test_dev.dev_bus_num = tb.dev.bus_num + + dev_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_bar1 = tb.rc.tree[0][0].bar_addr[1] + dev_bar3 = tb.rc.tree[0][0].bar_addr[3] + + for length in list(range(0, 8)): + for offset in list(range(8)): + tb.log.info("IO operation length: %d offset: %d", length, offset) + addr = dev_bar3+offset + test_data = bytearray([x % 256 for x in range(length)]) + + await tb.rc.io_write(addr, test_data, 5000) + assert tb.test_dev.regions[3][1][offset:offset+length] == test_data + + assert await tb.rc.io_read(addr, length, 5000) == test_data + + for length in list(range(0, 32))+[1024]: + for offset in list(range(8))+list(range(4096-8, 4096)): + tb.log.info("Memory operation (32-bit BAR) length: %d offset: %d", length, offset) + addr = dev_bar0+offset + test_data = bytearray([x % 256 for x in range(length)]) + + await tb.rc.mem_write(addr, test_data, 100) + # wait for write to complete + await tb.rc.mem_read(addr, 1, 5000) + assert tb.test_dev.regions[0][1][offset:offset+length] == test_data + + assert await tb.rc.mem_read(addr, length, 5000) == test_data + + for length in list(range(0, 32))+[1024]: + for offset in list(range(8))+list(range(4096-8, 4096)): + tb.log.info("Memory operation (64-bit BAR) length: %d offset: %d", length, offset) + addr = dev_bar1+offset + test_data = bytearray([x % 256 for x in range(length)]) + + await tb.rc.mem_write(addr, test_data, 100) + # wait for write to complete + await tb.rc.mem_read(addr, 1, 5000) + assert tb.test_dev.regions[1][1][offset:offset+length] == test_data + + assert await tb.rc.mem_read(addr, length, 5000) == test_data + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_dma(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + mem_base, mem_data = tb.rc.alloc_region(1024*1024) + io_base, io_data = tb.rc.alloc_io_region(1024) + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + await FallingEdge(dut.rst) + await Timer(100, 'ns') + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + tb.test_dev.dev_max_payload = tb.dev.functions[0].pcie_cap.max_payload_size + tb.test_dev.dev_max_read_req = tb.dev.functions[0].pcie_cap.max_read_request_size + tb.test_dev.dev_bus_num = tb.dev.bus_num + + for length in list(range(0, 32))+[1024]: + for offset in list(range(8))+list(range(4096-8, 4096)): + tb.log.info("Memory operation (DMA) length: %d offset: %d", length, offset) + addr = mem_base+offset + test_data = bytearray([x % 256 for x in range(length)]) + + await tb.test_dev.dma_mem_write(addr, test_data, 5000, 'ns') + # wait for write to complete + while not tb.test_dev.tx_wr_req_tlp_source.empty() or tb.test_dev.tx_wr_req_tlp_source.active: + await RisingEdge(dut.clk) + await tb.test_dev.dma_mem_read(addr, length, 5000, 'ns') + assert mem_data[offset:offset+length] == test_data + + assert await tb.test_dev.dma_mem_read(addr, length, 5000, 'ns') == test_data + + for length in list(range(0, 8)): + for offset in list(range(8)): + tb.log.info("IO operation (DMA) length: %d offset: %d", length, offset) + addr = io_base+offset + test_data = bytearray([x % 256 for x in range(length)]) + + await tb.test_dev.dma_io_write(addr, test_data, 5000, 'ns') + assert io_data[offset:offset+length] == test_data + + assert await tb.test_dev.dma_io_read(addr, length, 5000, 'ns') == test_data + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_dma_errors(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + await FallingEdge(dut.rst) + await Timer(100, 'ns') + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + mem_base, mem_data = tb.rc.alloc_region(1024*1024) + + tb.test_dev.dev_max_payload = tb.dev.functions[0].pcie_cap.max_payload_size + tb.test_dev.dev_max_read_req = tb.dev.functions[0].pcie_cap.max_read_request_size + tb.test_dev.dev_bus_num = tb.dev.bus_num + + tb.log.info("Memory operation (DMA) bad read (UR) short") + + try: + await tb.test_dev.dma_mem_read(mem_base - 1024, 8, 5000, 'ns') + except Exception: + pass + else: + assert False, "Expected exception" + + tb.log.info("Memory operation (DMA) bad read (UR) first") + + try: + await tb.test_dev.dma_mem_read(mem_base - 512, 1024, 5000, 'ns') + except Exception: + pass + else: + assert False, "Expected exception" + + tb.log.info("Memory operation (DMA) bad read (UR) last") + + try: + await tb.test_dev.dma_mem_read(mem_base + 1024*1024 - 512, 1024, 5000, 'ns') + except Exception: + pass + else: + assert False, "Expected exception" + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_msi(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + await FallingEdge(dut.rst) + await Timer(100, 'ns') + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + for k in range(32): + tb.log.info("Send MSI %d", k) + + await RisingEdge(dut.clk) + tb.dut.msi_irq <= 1 << k + await RisingEdge(dut.clk) + tb.dut.msi_irq <= 0 + + event = tb.rc.msi_get_event(tb.dev.functions[0].pcie_id, k) + event.clear() + await event.wait() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_fifos(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + await FallingEdge(dut.rst) + await Timer(100, 'ns') + + await tb.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + tb.test_dev.dev_max_payload = tb.dev.functions[0].pcie_cap.max_payload_size + tb.test_dev.dev_max_read_req = tb.dev.functions[0].pcie_cap.max_read_request_size + tb.test_dev.dev_bus_num = tb.dev.bus_num + + dev_bar0 = tb.rc.tree[0][0].bar_addr[0] + + test_data = bytearray([x for x in range(256)]) + + for k in range(64): + addr = dev_bar0+k*256 + await tb.rc.mem_write(addr, test_data, 100) + + for k in range(64): + addr = dev_bar0+k*256 + assert await tb.rc.mem_read(addr, len(test_data), 50000) == test_data + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +if cocotb.SIM_NAME: + + for test in [ + run_test_mem, + run_test_dma, + run_test_dma_errors, + run_test_msi, + ]: + + factory = TestFactory(test) + factory.add_option(("idle_inserter", "backpressure_inserter"), [(None, None), (cycle_pause, cycle_pause)]) + factory.generate_tests() + + factory = TestFactory(run_test_fifos) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.add_option("backpressure_inserter", [None, cycle_pause]) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) + + +@pytest.mark.parametrize("data_width", [256]) +@pytest.mark.parametrize("l_tile", [0]) +def test_pcie_s10_if(request, data_width, l_tile): + dut = "pcie_s10_if" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, f"{dut}_rx.v"), + os.path.join(rtl_dir, f"{dut}_tx.v"), + os.path.join(rtl_dir, "pcie_s10_cfg.v"), + os.path.join(rtl_dir, "pcie_s10_msi.v"), + os.path.join(rtl_dir, "arbiter.v"), + os.path.join(rtl_dir, "priority_encoder.v"), + ] + + parameters = {} + + # segmented interface parameters + tlp_seg_count = 1 + tlp_seg_data_width = data_width // tlp_seg_count + tlp_seg_strb_width = tlp_seg_data_width // 32 + + parameters['SEG_COUNT'] = 2 if data_width == 512 else 1 + parameters['SEG_DATA_WIDTH'] = data_width // parameters['SEG_COUNT'] + parameters['SEG_EMPTY_WIDTH'] = ((parameters['SEG_DATA_WIDTH'] // 32) - 1).bit_length() + parameters['TLP_SEG_COUNT'] = tlp_seg_count + parameters['TLP_SEG_DATA_WIDTH'] = tlp_seg_data_width + parameters['TLP_SEG_STRB_WIDTH'] = tlp_seg_strb_width + parameters['TLP_SEG_HDR_WIDTH'] = 128 + parameters['TX_SEQ_NUM_WIDTH'] = 6 + parameters['L_TILE'] = l_tile + parameters['PF_COUNT'] = 1 + parameters['VF_COUNT'] = 0 + parameters['F_COUNT'] = parameters['PF_COUNT']+parameters['VF_COUNT'] + parameters['IO_BAR_INDEX'] = 3 + parameters['MSI_ENABLE'] = 1 + parameters['MSI_COUNT'] = 32 + + 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, + )