mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
merged changes in eth
This commit is contained in:
commit
1ca0151b97
@ -55,6 +55,8 @@ following boards:
|
|||||||
* Intel Stratix 10 DX dev kit (Intel Stratix 10 DX 1SD280PT2F55E1VG)
|
* Intel Stratix 10 DX dev kit (Intel Stratix 10 DX 1SD280PT2F55E1VG)
|
||||||
* Intel Stratix 10 MX dev kit (Intel Stratix 10 MX 1SM21CHU1F53E1VG)
|
* Intel Stratix 10 MX dev kit (Intel Stratix 10 MX 1SM21CHU1F53E1VG)
|
||||||
* Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50)
|
* Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50)
|
||||||
|
* Xilinx Alveo U55C (Xilinx Virtex UltraScale+ XCU55C)
|
||||||
|
* Xilinx Alveo U55N/Varium C1100 (Xilinx Virtex UltraScale+ XCU55N)
|
||||||
* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
|
* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
|
||||||
* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
|
* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
|
||||||
* Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
|
* Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
|
||||||
|
@ -1,670 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014-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 core logic
|
|
||||||
*/
|
|
||||||
module fpga_core #
|
|
||||||
(
|
|
||||||
parameter TARGET = "XILINX"
|
|
||||||
)
|
|
||||||
(
|
|
||||||
/*
|
|
||||||
* Clock: 156.25MHz
|
|
||||||
* Synchronous reset
|
|
||||||
*/
|
|
||||||
input wire clk,
|
|
||||||
input wire rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO
|
|
||||||
*/
|
|
||||||
input wire [3:0] sw,
|
|
||||||
output wire [2:0] led,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ethernet: QSFP28
|
|
||||||
*/
|
|
||||||
input wire qsfp0_tx_clk_1,
|
|
||||||
input wire qsfp0_tx_rst_1,
|
|
||||||
output wire [63:0] qsfp0_txd_1,
|
|
||||||
output wire [7:0] qsfp0_txc_1,
|
|
||||||
input wire qsfp0_rx_clk_1,
|
|
||||||
input wire qsfp0_rx_rst_1,
|
|
||||||
input wire [63:0] qsfp0_rxd_1,
|
|
||||||
input wire [7:0] qsfp0_rxc_1,
|
|
||||||
input wire qsfp0_tx_clk_2,
|
|
||||||
input wire qsfp0_tx_rst_2,
|
|
||||||
output wire [63:0] qsfp0_txd_2,
|
|
||||||
output wire [7:0] qsfp0_txc_2,
|
|
||||||
input wire qsfp0_rx_clk_2,
|
|
||||||
input wire qsfp0_rx_rst_2,
|
|
||||||
input wire [63:0] qsfp0_rxd_2,
|
|
||||||
input wire [7:0] qsfp0_rxc_2,
|
|
||||||
input wire qsfp0_tx_clk_3,
|
|
||||||
input wire qsfp0_tx_rst_3,
|
|
||||||
output wire [63:0] qsfp0_txd_3,
|
|
||||||
output wire [7:0] qsfp0_txc_3,
|
|
||||||
input wire qsfp0_rx_clk_3,
|
|
||||||
input wire qsfp0_rx_rst_3,
|
|
||||||
input wire [63:0] qsfp0_rxd_3,
|
|
||||||
input wire [7:0] qsfp0_rxc_3,
|
|
||||||
input wire qsfp0_tx_clk_4,
|
|
||||||
input wire qsfp0_tx_rst_4,
|
|
||||||
output wire [63:0] qsfp0_txd_4,
|
|
||||||
output wire [7:0] qsfp0_txc_4,
|
|
||||||
input wire qsfp0_rx_clk_4,
|
|
||||||
input wire qsfp0_rx_rst_4,
|
|
||||||
input wire [63:0] qsfp0_rxd_4,
|
|
||||||
input wire [7:0] qsfp0_rxc_4,
|
|
||||||
input wire qsfp1_tx_clk_1,
|
|
||||||
input wire qsfp1_tx_rst_1,
|
|
||||||
output wire [63:0] qsfp1_txd_1,
|
|
||||||
output wire [7:0] qsfp1_txc_1,
|
|
||||||
input wire qsfp1_rx_clk_1,
|
|
||||||
input wire qsfp1_rx_rst_1,
|
|
||||||
input wire [63:0] qsfp1_rxd_1,
|
|
||||||
input wire [7:0] qsfp1_rxc_1,
|
|
||||||
input wire qsfp1_tx_clk_2,
|
|
||||||
input wire qsfp1_tx_rst_2,
|
|
||||||
output wire [63:0] qsfp1_txd_2,
|
|
||||||
output wire [7:0] qsfp1_txc_2,
|
|
||||||
input wire qsfp1_rx_clk_2,
|
|
||||||
input wire qsfp1_rx_rst_2,
|
|
||||||
input wire [63:0] qsfp1_rxd_2,
|
|
||||||
input wire [7:0] qsfp1_rxc_2,
|
|
||||||
input wire qsfp1_tx_clk_3,
|
|
||||||
input wire qsfp1_tx_rst_3,
|
|
||||||
output wire [63:0] qsfp1_txd_3,
|
|
||||||
output wire [7:0] qsfp1_txc_3,
|
|
||||||
input wire qsfp1_rx_clk_3,
|
|
||||||
input wire qsfp1_rx_rst_3,
|
|
||||||
input wire [63:0] qsfp1_rxd_3,
|
|
||||||
input wire [7:0] qsfp1_rxc_3,
|
|
||||||
input wire qsfp1_tx_clk_4,
|
|
||||||
input wire qsfp1_tx_rst_4,
|
|
||||||
output wire [63:0] qsfp1_txd_4,
|
|
||||||
output wire [7:0] qsfp1_txc_4,
|
|
||||||
input wire qsfp1_rx_clk_4,
|
|
||||||
input wire qsfp1_rx_rst_4,
|
|
||||||
input wire [63:0] qsfp1_rxd_4,
|
|
||||||
input wire [7:0] qsfp1_rxc_4,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UART: 115200 bps, 8N1
|
|
||||||
*/
|
|
||||||
output wire uart_rxd,
|
|
||||||
input wire uart_txd
|
|
||||||
);
|
|
||||||
|
|
||||||
// AXI between MAC and Ethernet modules
|
|
||||||
wire [63:0] rx_axis_tdata;
|
|
||||||
wire [7:0] rx_axis_tkeep;
|
|
||||||
wire rx_axis_tvalid;
|
|
||||||
wire rx_axis_tready;
|
|
||||||
wire rx_axis_tlast;
|
|
||||||
wire rx_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] tx_axis_tdata;
|
|
||||||
wire [7:0] tx_axis_tkeep;
|
|
||||||
wire tx_axis_tvalid;
|
|
||||||
wire tx_axis_tready;
|
|
||||||
wire tx_axis_tlast;
|
|
||||||
wire tx_axis_tuser;
|
|
||||||
|
|
||||||
// Ethernet frame between Ethernet modules and UDP stack
|
|
||||||
wire rx_eth_hdr_ready;
|
|
||||||
wire rx_eth_hdr_valid;
|
|
||||||
wire [47:0] rx_eth_dest_mac;
|
|
||||||
wire [47:0] rx_eth_src_mac;
|
|
||||||
wire [15:0] rx_eth_type;
|
|
||||||
wire [63:0] rx_eth_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_eth_payload_axis_tkeep;
|
|
||||||
wire rx_eth_payload_axis_tvalid;
|
|
||||||
wire rx_eth_payload_axis_tready;
|
|
||||||
wire rx_eth_payload_axis_tlast;
|
|
||||||
wire rx_eth_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_eth_hdr_ready;
|
|
||||||
wire tx_eth_hdr_valid;
|
|
||||||
wire [47:0] tx_eth_dest_mac;
|
|
||||||
wire [47:0] tx_eth_src_mac;
|
|
||||||
wire [15:0] tx_eth_type;
|
|
||||||
wire [63:0] tx_eth_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_eth_payload_axis_tkeep;
|
|
||||||
wire tx_eth_payload_axis_tvalid;
|
|
||||||
wire tx_eth_payload_axis_tready;
|
|
||||||
wire tx_eth_payload_axis_tlast;
|
|
||||||
wire tx_eth_payload_axis_tuser;
|
|
||||||
|
|
||||||
// IP frame connections
|
|
||||||
wire rx_ip_hdr_valid;
|
|
||||||
wire rx_ip_hdr_ready;
|
|
||||||
wire [47:0] rx_ip_eth_dest_mac;
|
|
||||||
wire [47:0] rx_ip_eth_src_mac;
|
|
||||||
wire [15:0] rx_ip_eth_type;
|
|
||||||
wire [3:0] rx_ip_version;
|
|
||||||
wire [3:0] rx_ip_ihl;
|
|
||||||
wire [5:0] rx_ip_dscp;
|
|
||||||
wire [1:0] rx_ip_ecn;
|
|
||||||
wire [15:0] rx_ip_length;
|
|
||||||
wire [15:0] rx_ip_identification;
|
|
||||||
wire [2:0] rx_ip_flags;
|
|
||||||
wire [12:0] rx_ip_fragment_offset;
|
|
||||||
wire [7:0] rx_ip_ttl;
|
|
||||||
wire [7:0] rx_ip_protocol;
|
|
||||||
wire [15:0] rx_ip_header_checksum;
|
|
||||||
wire [31:0] rx_ip_source_ip;
|
|
||||||
wire [31:0] rx_ip_dest_ip;
|
|
||||||
wire [63:0] rx_ip_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_ip_payload_axis_tkeep;
|
|
||||||
wire rx_ip_payload_axis_tvalid;
|
|
||||||
wire rx_ip_payload_axis_tready;
|
|
||||||
wire rx_ip_payload_axis_tlast;
|
|
||||||
wire rx_ip_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_ip_hdr_valid;
|
|
||||||
wire tx_ip_hdr_ready;
|
|
||||||
wire [5:0] tx_ip_dscp;
|
|
||||||
wire [1:0] tx_ip_ecn;
|
|
||||||
wire [15:0] tx_ip_length;
|
|
||||||
wire [7:0] tx_ip_ttl;
|
|
||||||
wire [7:0] tx_ip_protocol;
|
|
||||||
wire [31:0] tx_ip_source_ip;
|
|
||||||
wire [31:0] tx_ip_dest_ip;
|
|
||||||
wire [63:0] tx_ip_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_ip_payload_axis_tkeep;
|
|
||||||
wire tx_ip_payload_axis_tvalid;
|
|
||||||
wire tx_ip_payload_axis_tready;
|
|
||||||
wire tx_ip_payload_axis_tlast;
|
|
||||||
wire tx_ip_payload_axis_tuser;
|
|
||||||
|
|
||||||
// UDP frame connections
|
|
||||||
wire rx_udp_hdr_valid;
|
|
||||||
wire rx_udp_hdr_ready;
|
|
||||||
wire [47:0] rx_udp_eth_dest_mac;
|
|
||||||
wire [47:0] rx_udp_eth_src_mac;
|
|
||||||
wire [15:0] rx_udp_eth_type;
|
|
||||||
wire [3:0] rx_udp_ip_version;
|
|
||||||
wire [3:0] rx_udp_ip_ihl;
|
|
||||||
wire [5:0] rx_udp_ip_dscp;
|
|
||||||
wire [1:0] rx_udp_ip_ecn;
|
|
||||||
wire [15:0] rx_udp_ip_length;
|
|
||||||
wire [15:0] rx_udp_ip_identification;
|
|
||||||
wire [2:0] rx_udp_ip_flags;
|
|
||||||
wire [12:0] rx_udp_ip_fragment_offset;
|
|
||||||
wire [7:0] rx_udp_ip_ttl;
|
|
||||||
wire [7:0] rx_udp_ip_protocol;
|
|
||||||
wire [15:0] rx_udp_ip_header_checksum;
|
|
||||||
wire [31:0] rx_udp_ip_source_ip;
|
|
||||||
wire [31:0] rx_udp_ip_dest_ip;
|
|
||||||
wire [15:0] rx_udp_source_port;
|
|
||||||
wire [15:0] rx_udp_dest_port;
|
|
||||||
wire [15:0] rx_udp_length;
|
|
||||||
wire [15:0] rx_udp_checksum;
|
|
||||||
wire [63:0] rx_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_udp_payload_axis_tkeep;
|
|
||||||
wire rx_udp_payload_axis_tvalid;
|
|
||||||
wire rx_udp_payload_axis_tready;
|
|
||||||
wire rx_udp_payload_axis_tlast;
|
|
||||||
wire rx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_udp_hdr_valid;
|
|
||||||
wire tx_udp_hdr_ready;
|
|
||||||
wire [5:0] tx_udp_ip_dscp;
|
|
||||||
wire [1:0] tx_udp_ip_ecn;
|
|
||||||
wire [7:0] tx_udp_ip_ttl;
|
|
||||||
wire [31:0] tx_udp_ip_source_ip;
|
|
||||||
wire [31:0] tx_udp_ip_dest_ip;
|
|
||||||
wire [15:0] tx_udp_source_port;
|
|
||||||
wire [15:0] tx_udp_dest_port;
|
|
||||||
wire [15:0] tx_udp_length;
|
|
||||||
wire [15:0] tx_udp_checksum;
|
|
||||||
wire [63:0] tx_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_udp_payload_axis_tkeep;
|
|
||||||
wire tx_udp_payload_axis_tvalid;
|
|
||||||
wire tx_udp_payload_axis_tready;
|
|
||||||
wire tx_udp_payload_axis_tlast;
|
|
||||||
wire tx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] rx_fifo_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_fifo_udp_payload_axis_tkeep;
|
|
||||||
wire rx_fifo_udp_payload_axis_tvalid;
|
|
||||||
wire rx_fifo_udp_payload_axis_tready;
|
|
||||||
wire rx_fifo_udp_payload_axis_tlast;
|
|
||||||
wire rx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] tx_fifo_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_fifo_udp_payload_axis_tkeep;
|
|
||||||
wire tx_fifo_udp_payload_axis_tvalid;
|
|
||||||
wire tx_fifo_udp_payload_axis_tready;
|
|
||||||
wire tx_fifo_udp_payload_axis_tlast;
|
|
||||||
wire tx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
// Configuration
|
|
||||||
wire [47:0] local_mac = 48'h02_00_00_00_00_00;
|
|
||||||
wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128};
|
|
||||||
wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1};
|
|
||||||
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
|
|
||||||
|
|
||||||
// IP ports not used
|
|
||||||
assign rx_ip_hdr_ready = 1;
|
|
||||||
assign rx_ip_payload_axis_tready = 1;
|
|
||||||
|
|
||||||
assign tx_ip_hdr_valid = 0;
|
|
||||||
assign tx_ip_dscp = 0;
|
|
||||||
assign tx_ip_ecn = 0;
|
|
||||||
assign tx_ip_length = 0;
|
|
||||||
assign tx_ip_ttl = 0;
|
|
||||||
assign tx_ip_protocol = 0;
|
|
||||||
assign tx_ip_source_ip = 0;
|
|
||||||
assign tx_ip_dest_ip = 0;
|
|
||||||
assign tx_ip_payload_axis_tdata = 0;
|
|
||||||
assign tx_ip_payload_axis_tkeep = 0;
|
|
||||||
assign tx_ip_payload_axis_tvalid = 0;
|
|
||||||
assign tx_ip_payload_axis_tlast = 0;
|
|
||||||
assign tx_ip_payload_axis_tuser = 0;
|
|
||||||
|
|
||||||
// Loop back UDP
|
|
||||||
wire match_cond = rx_udp_dest_port == 1234;
|
|
||||||
wire no_match = !match_cond;
|
|
||||||
|
|
||||||
reg match_cond_reg = 0;
|
|
||||||
reg no_match_reg = 0;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (rst) begin
|
|
||||||
match_cond_reg <= 0;
|
|
||||||
no_match_reg <= 0;
|
|
||||||
end else begin
|
|
||||||
if (rx_udp_payload_axis_tvalid) begin
|
|
||||||
if ((!match_cond_reg && !no_match_reg) ||
|
|
||||||
(rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
|
|
||||||
match_cond_reg <= match_cond;
|
|
||||||
no_match_reg <= no_match;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
match_cond_reg <= 0;
|
|
||||||
no_match_reg <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
|
|
||||||
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
|
|
||||||
assign tx_udp_ip_dscp = 0;
|
|
||||||
assign tx_udp_ip_ecn = 0;
|
|
||||||
assign tx_udp_ip_ttl = 64;
|
|
||||||
assign tx_udp_ip_source_ip = local_ip;
|
|
||||||
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
|
|
||||||
assign tx_udp_source_port = rx_udp_dest_port;
|
|
||||||
assign tx_udp_dest_port = rx_udp_source_port;
|
|
||||||
assign tx_udp_length = rx_udp_length;
|
|
||||||
assign tx_udp_checksum = 0;
|
|
||||||
|
|
||||||
assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
|
|
||||||
assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep;
|
|
||||||
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
|
|
||||||
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
|
|
||||||
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
|
|
||||||
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
|
|
||||||
assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep;
|
|
||||||
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
|
|
||||||
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
|
|
||||||
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
|
|
||||||
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
// Place first payload byte onto LEDs
|
|
||||||
reg valid_last = 0;
|
|
||||||
reg [7:0] led_reg = 0;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (rst) begin
|
|
||||||
led_reg <= 0;
|
|
||||||
end else begin
|
|
||||||
valid_last <= tx_udp_payload_axis_tvalid;
|
|
||||||
if (tx_udp_payload_axis_tvalid && !valid_last) begin
|
|
||||||
led_reg <= tx_udp_payload_axis_tdata;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
//assign led = sw;
|
|
||||||
assign led = led_reg;
|
|
||||||
|
|
||||||
assign qsfp0_txd_2 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_2 = 8'hff;
|
|
||||||
assign qsfp0_txd_3 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_3 = 8'hff;
|
|
||||||
assign qsfp0_txd_4 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_4 = 8'hff;
|
|
||||||
|
|
||||||
assign qsfp1_txd_1 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_1 = 8'hff;
|
|
||||||
assign qsfp1_txd_2 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_2 = 8'hff;
|
|
||||||
assign qsfp1_txd_3 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_3 = 8'hff;
|
|
||||||
assign qsfp1_txd_4 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_4 = 8'hff;
|
|
||||||
|
|
||||||
eth_mac_10g_fifo #(
|
|
||||||
.ENABLE_PADDING(1),
|
|
||||||
.ENABLE_DIC(1),
|
|
||||||
.MIN_FRAME_LENGTH(64),
|
|
||||||
.TX_FIFO_DEPTH(4096),
|
|
||||||
.TX_FRAME_FIFO(1),
|
|
||||||
.RX_FIFO_DEPTH(4096),
|
|
||||||
.RX_FRAME_FIFO(1)
|
|
||||||
)
|
|
||||||
eth_mac_10g_fifo_inst (
|
|
||||||
.rx_clk(qsfp0_rx_clk_1),
|
|
||||||
.rx_rst(qsfp0_rx_rst_1),
|
|
||||||
.tx_clk(qsfp0_tx_clk_1),
|
|
||||||
.tx_rst(qsfp0_tx_rst_1),
|
|
||||||
.logic_clk(clk),
|
|
||||||
.logic_rst(rst),
|
|
||||||
|
|
||||||
.tx_axis_tdata(tx_axis_tdata),
|
|
||||||
.tx_axis_tkeep(tx_axis_tkeep),
|
|
||||||
.tx_axis_tvalid(tx_axis_tvalid),
|
|
||||||
.tx_axis_tready(tx_axis_tready),
|
|
||||||
.tx_axis_tlast(tx_axis_tlast),
|
|
||||||
.tx_axis_tuser(tx_axis_tuser),
|
|
||||||
|
|
||||||
.rx_axis_tdata(rx_axis_tdata),
|
|
||||||
.rx_axis_tkeep(rx_axis_tkeep),
|
|
||||||
.rx_axis_tvalid(rx_axis_tvalid),
|
|
||||||
.rx_axis_tready(rx_axis_tready),
|
|
||||||
.rx_axis_tlast(rx_axis_tlast),
|
|
||||||
.rx_axis_tuser(rx_axis_tuser),
|
|
||||||
|
|
||||||
.xgmii_rxd(qsfp0_rxd_1),
|
|
||||||
.xgmii_rxc(qsfp0_rxc_1),
|
|
||||||
.xgmii_txd(qsfp0_txd_1),
|
|
||||||
.xgmii_txc(qsfp0_txc_1),
|
|
||||||
|
|
||||||
.tx_fifo_overflow(),
|
|
||||||
.tx_fifo_bad_frame(),
|
|
||||||
.tx_fifo_good_frame(),
|
|
||||||
.rx_error_bad_frame(),
|
|
||||||
.rx_error_bad_fcs(),
|
|
||||||
.rx_fifo_overflow(),
|
|
||||||
.rx_fifo_bad_frame(),
|
|
||||||
.rx_fifo_good_frame(),
|
|
||||||
|
|
||||||
.cfg_ifg(8'd12),
|
|
||||||
.cfg_tx_enable(1'b1),
|
|
||||||
.cfg_rx_enable(1'b1)
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_axis_rx #(
|
|
||||||
.DATA_WIDTH(64)
|
|
||||||
)
|
|
||||||
eth_axis_rx_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// AXI input
|
|
||||||
.s_axis_tdata(rx_axis_tdata),
|
|
||||||
.s_axis_tkeep(rx_axis_tkeep),
|
|
||||||
.s_axis_tvalid(rx_axis_tvalid),
|
|
||||||
.s_axis_tready(rx_axis_tready),
|
|
||||||
.s_axis_tlast(rx_axis_tlast),
|
|
||||||
.s_axis_tuser(rx_axis_tuser),
|
|
||||||
// Ethernet frame output
|
|
||||||
.m_eth_hdr_valid(rx_eth_hdr_valid),
|
|
||||||
.m_eth_hdr_ready(rx_eth_hdr_ready),
|
|
||||||
.m_eth_dest_mac(rx_eth_dest_mac),
|
|
||||||
.m_eth_src_mac(rx_eth_src_mac),
|
|
||||||
.m_eth_type(rx_eth_type),
|
|
||||||
.m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
|
||||||
.m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
|
|
||||||
.m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
|
||||||
.m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
|
||||||
.m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
|
||||||
.m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.busy(),
|
|
||||||
.error_header_early_termination()
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_axis_tx #(
|
|
||||||
.DATA_WIDTH(64)
|
|
||||||
)
|
|
||||||
eth_axis_tx_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// Ethernet frame input
|
|
||||||
.s_eth_hdr_valid(tx_eth_hdr_valid),
|
|
||||||
.s_eth_hdr_ready(tx_eth_hdr_ready),
|
|
||||||
.s_eth_dest_mac(tx_eth_dest_mac),
|
|
||||||
.s_eth_src_mac(tx_eth_src_mac),
|
|
||||||
.s_eth_type(tx_eth_type),
|
|
||||||
.s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
|
||||||
.s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
|
|
||||||
.s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
|
||||||
.s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
|
||||||
.s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
|
||||||
.s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
|
||||||
// AXI output
|
|
||||||
.m_axis_tdata(tx_axis_tdata),
|
|
||||||
.m_axis_tkeep(tx_axis_tkeep),
|
|
||||||
.m_axis_tvalid(tx_axis_tvalid),
|
|
||||||
.m_axis_tready(tx_axis_tready),
|
|
||||||
.m_axis_tlast(tx_axis_tlast),
|
|
||||||
.m_axis_tuser(tx_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.busy()
|
|
||||||
);
|
|
||||||
|
|
||||||
udp_complete_64
|
|
||||||
udp_complete_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// Ethernet frame input
|
|
||||||
.s_eth_hdr_valid(rx_eth_hdr_valid),
|
|
||||||
.s_eth_hdr_ready(rx_eth_hdr_ready),
|
|
||||||
.s_eth_dest_mac(rx_eth_dest_mac),
|
|
||||||
.s_eth_src_mac(rx_eth_src_mac),
|
|
||||||
.s_eth_type(rx_eth_type),
|
|
||||||
.s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
|
||||||
.s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
|
|
||||||
.s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
|
||||||
.s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
|
||||||
.s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
|
||||||
.s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
|
||||||
// Ethernet frame output
|
|
||||||
.m_eth_hdr_valid(tx_eth_hdr_valid),
|
|
||||||
.m_eth_hdr_ready(tx_eth_hdr_ready),
|
|
||||||
.m_eth_dest_mac(tx_eth_dest_mac),
|
|
||||||
.m_eth_src_mac(tx_eth_src_mac),
|
|
||||||
.m_eth_type(tx_eth_type),
|
|
||||||
.m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
|
||||||
.m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
|
|
||||||
.m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
|
||||||
.m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
|
||||||
.m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
|
||||||
.m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
|
||||||
// IP frame input
|
|
||||||
.s_ip_hdr_valid(tx_ip_hdr_valid),
|
|
||||||
.s_ip_hdr_ready(tx_ip_hdr_ready),
|
|
||||||
.s_ip_dscp(tx_ip_dscp),
|
|
||||||
.s_ip_ecn(tx_ip_ecn),
|
|
||||||
.s_ip_length(tx_ip_length),
|
|
||||||
.s_ip_ttl(tx_ip_ttl),
|
|
||||||
.s_ip_protocol(tx_ip_protocol),
|
|
||||||
.s_ip_source_ip(tx_ip_source_ip),
|
|
||||||
.s_ip_dest_ip(tx_ip_dest_ip),
|
|
||||||
.s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
|
|
||||||
.s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep),
|
|
||||||
.s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
|
|
||||||
.s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
|
|
||||||
.s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
|
|
||||||
.s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
|
|
||||||
// IP frame output
|
|
||||||
.m_ip_hdr_valid(rx_ip_hdr_valid),
|
|
||||||
.m_ip_hdr_ready(rx_ip_hdr_ready),
|
|
||||||
.m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
|
|
||||||
.m_ip_eth_src_mac(rx_ip_eth_src_mac),
|
|
||||||
.m_ip_eth_type(rx_ip_eth_type),
|
|
||||||
.m_ip_version(rx_ip_version),
|
|
||||||
.m_ip_ihl(rx_ip_ihl),
|
|
||||||
.m_ip_dscp(rx_ip_dscp),
|
|
||||||
.m_ip_ecn(rx_ip_ecn),
|
|
||||||
.m_ip_length(rx_ip_length),
|
|
||||||
.m_ip_identification(rx_ip_identification),
|
|
||||||
.m_ip_flags(rx_ip_flags),
|
|
||||||
.m_ip_fragment_offset(rx_ip_fragment_offset),
|
|
||||||
.m_ip_ttl(rx_ip_ttl),
|
|
||||||
.m_ip_protocol(rx_ip_protocol),
|
|
||||||
.m_ip_header_checksum(rx_ip_header_checksum),
|
|
||||||
.m_ip_source_ip(rx_ip_source_ip),
|
|
||||||
.m_ip_dest_ip(rx_ip_dest_ip),
|
|
||||||
.m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
|
|
||||||
.m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep),
|
|
||||||
.m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
|
|
||||||
.m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
|
|
||||||
.m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
|
|
||||||
.m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
|
|
||||||
// UDP frame input
|
|
||||||
.s_udp_hdr_valid(tx_udp_hdr_valid),
|
|
||||||
.s_udp_hdr_ready(tx_udp_hdr_ready),
|
|
||||||
.s_udp_ip_dscp(tx_udp_ip_dscp),
|
|
||||||
.s_udp_ip_ecn(tx_udp_ip_ecn),
|
|
||||||
.s_udp_ip_ttl(tx_udp_ip_ttl),
|
|
||||||
.s_udp_ip_source_ip(tx_udp_ip_source_ip),
|
|
||||||
.s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
|
|
||||||
.s_udp_source_port(tx_udp_source_port),
|
|
||||||
.s_udp_dest_port(tx_udp_dest_port),
|
|
||||||
.s_udp_length(tx_udp_length),
|
|
||||||
.s_udp_checksum(tx_udp_checksum),
|
|
||||||
.s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
|
|
||||||
.s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep),
|
|
||||||
.s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
|
|
||||||
.s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
|
|
||||||
.s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
|
|
||||||
.s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
|
|
||||||
// UDP frame output
|
|
||||||
.m_udp_hdr_valid(rx_udp_hdr_valid),
|
|
||||||
.m_udp_hdr_ready(rx_udp_hdr_ready),
|
|
||||||
.m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
|
|
||||||
.m_udp_eth_src_mac(rx_udp_eth_src_mac),
|
|
||||||
.m_udp_eth_type(rx_udp_eth_type),
|
|
||||||
.m_udp_ip_version(rx_udp_ip_version),
|
|
||||||
.m_udp_ip_ihl(rx_udp_ip_ihl),
|
|
||||||
.m_udp_ip_dscp(rx_udp_ip_dscp),
|
|
||||||
.m_udp_ip_ecn(rx_udp_ip_ecn),
|
|
||||||
.m_udp_ip_length(rx_udp_ip_length),
|
|
||||||
.m_udp_ip_identification(rx_udp_ip_identification),
|
|
||||||
.m_udp_ip_flags(rx_udp_ip_flags),
|
|
||||||
.m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
|
|
||||||
.m_udp_ip_ttl(rx_udp_ip_ttl),
|
|
||||||
.m_udp_ip_protocol(rx_udp_ip_protocol),
|
|
||||||
.m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
|
|
||||||
.m_udp_ip_source_ip(rx_udp_ip_source_ip),
|
|
||||||
.m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
|
|
||||||
.m_udp_source_port(rx_udp_source_port),
|
|
||||||
.m_udp_dest_port(rx_udp_dest_port),
|
|
||||||
.m_udp_length(rx_udp_length),
|
|
||||||
.m_udp_checksum(rx_udp_checksum),
|
|
||||||
.m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
|
|
||||||
.m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep),
|
|
||||||
.m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
|
|
||||||
.m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
|
|
||||||
.m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
|
|
||||||
.m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.ip_rx_busy(),
|
|
||||||
.ip_tx_busy(),
|
|
||||||
.udp_rx_busy(),
|
|
||||||
.udp_tx_busy(),
|
|
||||||
.ip_rx_error_header_early_termination(),
|
|
||||||
.ip_rx_error_payload_early_termination(),
|
|
||||||
.ip_rx_error_invalid_header(),
|
|
||||||
.ip_rx_error_invalid_checksum(),
|
|
||||||
.ip_tx_error_payload_early_termination(),
|
|
||||||
.ip_tx_error_arp_failed(),
|
|
||||||
.udp_rx_error_header_early_termination(),
|
|
||||||
.udp_rx_error_payload_early_termination(),
|
|
||||||
.udp_tx_error_payload_early_termination(),
|
|
||||||
// Configuration
|
|
||||||
.local_mac(local_mac),
|
|
||||||
.local_ip(local_ip),
|
|
||||||
.gateway_ip(gateway_ip),
|
|
||||||
.subnet_mask(subnet_mask),
|
|
||||||
.clear_arp_cache(1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_fifo #(
|
|
||||||
.DEPTH(8192),
|
|
||||||
.DATA_WIDTH(64),
|
|
||||||
.KEEP_ENABLE(1),
|
|
||||||
.KEEP_WIDTH(8),
|
|
||||||
.ID_ENABLE(0),
|
|
||||||
.DEST_ENABLE(0),
|
|
||||||
.USER_ENABLE(1),
|
|
||||||
.USER_WIDTH(1),
|
|
||||||
.FRAME_FIFO(0)
|
|
||||||
)
|
|
||||||
udp_payload_fifo (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
|
|
||||||
// AXI input
|
|
||||||
.s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
|
|
||||||
.s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep),
|
|
||||||
.s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
|
|
||||||
.s_axis_tready(rx_fifo_udp_payload_axis_tready),
|
|
||||||
.s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
|
|
||||||
.s_axis_tid(0),
|
|
||||||
.s_axis_tdest(0),
|
|
||||||
.s_axis_tuser(rx_fifo_udp_payload_axis_tuser),
|
|
||||||
|
|
||||||
// AXI output
|
|
||||||
.m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
|
|
||||||
.m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep),
|
|
||||||
.m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
|
|
||||||
.m_axis_tready(tx_fifo_udp_payload_axis_tready),
|
|
||||||
.m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
|
|
||||||
.m_axis_tid(),
|
|
||||||
.m_axis_tdest(),
|
|
||||||
.m_axis_tuser(tx_fifo_udp_payload_axis_tuser),
|
|
||||||
|
|
||||||
// Status
|
|
||||||
.status_overflow(),
|
|
||||||
.status_bad_frame(),
|
|
||||||
.status_good_frame()
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,229 +0,0 @@
|
|||||||
"""
|
|
||||||
|
|
||||||
Copyright (c) 2020 Alex Forencich
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
|
|
||||||
from scapy.layers.l2 import Ether, ARP
|
|
||||||
from scapy.layers.inet import IP, UDP
|
|
||||||
|
|
||||||
import cocotb_test.simulator
|
|
||||||
|
|
||||||
import cocotb
|
|
||||||
from cocotb.log import SimLog
|
|
||||||
from cocotb.clock import Clock
|
|
||||||
from cocotb.triggers import RisingEdge
|
|
||||||
|
|
||||||
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
|
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
|
||||||
def __init__(self, dut):
|
|
||||||
self.dut = dut
|
|
||||||
|
|
||||||
self.log = SimLog("cocotb.tb")
|
|
||||||
self.log.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start())
|
|
||||||
|
|
||||||
# Ethernet
|
|
||||||
self.qsfp_source = []
|
|
||||||
self.qsfp_sink = []
|
|
||||||
|
|
||||||
for x in range(2):
|
|
||||||
sources = []
|
|
||||||
sinks = []
|
|
||||||
for y in range(1, 5):
|
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_rx_clk_{y}"), 2.56, units="ns").start())
|
|
||||||
source = XgmiiSource(getattr(dut, f"qsfp{x}_rxd_{y}"), getattr(dut, f"qsfp{x}_rxc_{y}"), getattr(dut, f"qsfp{x}_rx_clk_{y}"), getattr(dut, f"qsfp{x}_rx_rst_{y}"))
|
|
||||||
sources.append(source)
|
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_tx_clk_{y}"), 2.56, units="ns").start())
|
|
||||||
sink = XgmiiSink(getattr(dut, f"qsfp{x}_txd_{y}"), getattr(dut, f"qsfp{x}_txc_{y}"), getattr(dut, f"qsfp{x}_tx_clk_{y}"), getattr(dut, f"qsfp{x}_tx_rst_{y}"))
|
|
||||||
sinks.append(sink)
|
|
||||||
self.qsfp_source.append(sources)
|
|
||||||
self.qsfp_sink.append(sinks)
|
|
||||||
|
|
||||||
dut.sw.setimmediatevalue(0)
|
|
||||||
|
|
||||||
async def init(self):
|
|
||||||
|
|
||||||
self.dut.rst.setimmediatevalue(0)
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").setimmediatevalue(0)
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").setimmediatevalue(0)
|
|
||||||
|
|
||||||
for k in range(10):
|
|
||||||
await RisingEdge(self.dut.clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 1
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 1
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 1
|
|
||||||
|
|
||||||
for k in range(10):
|
|
||||||
await RisingEdge(self.dut.clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 0
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 0
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 0
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def run_test(dut):
|
|
||||||
|
|
||||||
tb = TB(dut)
|
|
||||||
|
|
||||||
await tb.init()
|
|
||||||
|
|
||||||
tb.log.info("test UDP RX packet")
|
|
||||||
|
|
||||||
payload = bytes([x % 256 for x in range(256)])
|
|
||||||
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
|
|
||||||
ip = IP(src='192.168.1.100', dst='192.168.1.128')
|
|
||||||
udp = UDP(sport=5678, dport=1234)
|
|
||||||
test_pkt = eth / ip / udp / payload
|
|
||||||
|
|
||||||
test_frame = XgmiiFrame.from_payload(test_pkt.build())
|
|
||||||
|
|
||||||
await tb.qsfp_source[0][0].send(test_frame)
|
|
||||||
|
|
||||||
tb.log.info("receive ARP request")
|
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0][0].recv()
|
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
|
||||||
|
|
||||||
tb.log.info("RX packet: %s", repr(rx_pkt))
|
|
||||||
|
|
||||||
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
|
|
||||||
assert rx_pkt.src == test_pkt.dst
|
|
||||||
assert rx_pkt[ARP].hwtype == 1
|
|
||||||
assert rx_pkt[ARP].ptype == 0x0800
|
|
||||||
assert rx_pkt[ARP].hwlen == 6
|
|
||||||
assert rx_pkt[ARP].plen == 4
|
|
||||||
assert rx_pkt[ARP].op == 1
|
|
||||||
assert rx_pkt[ARP].hwsrc == test_pkt.dst
|
|
||||||
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
|
|
||||||
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
|
|
||||||
assert rx_pkt[ARP].pdst == test_pkt[IP].src
|
|
||||||
|
|
||||||
tb.log.info("send ARP response")
|
|
||||||
|
|
||||||
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
|
|
||||||
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
|
|
||||||
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
|
|
||||||
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
|
|
||||||
resp_pkt = eth / arp
|
|
||||||
|
|
||||||
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
|
|
||||||
|
|
||||||
await tb.qsfp_source[0][0].send(resp_frame)
|
|
||||||
|
|
||||||
tb.log.info("receive UDP packet")
|
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0][0].recv()
|
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
|
||||||
|
|
||||||
tb.log.info("RX packet: %s", repr(rx_pkt))
|
|
||||||
|
|
||||||
assert rx_pkt.dst == test_pkt.src
|
|
||||||
assert rx_pkt.src == test_pkt.dst
|
|
||||||
assert rx_pkt[IP].dst == test_pkt[IP].src
|
|
||||||
assert rx_pkt[IP].src == test_pkt[IP].dst
|
|
||||||
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
|
|
||||||
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
|
|
||||||
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
|
|
||||||
|
|
||||||
await RisingEdge(dut.clk)
|
|
||||||
await RisingEdge(dut.clk)
|
|
||||||
|
|
||||||
|
|
||||||
# cocotb-test
|
|
||||||
|
|
||||||
tests_dir = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
|
||||||
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
|
|
||||||
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
|
|
||||||
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl'))
|
|
||||||
|
|
||||||
|
|
||||||
def test_fpga_core(request):
|
|
||||||
dut = "fpga_core"
|
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
|
||||||
toplevel = dut
|
|
||||||
|
|
||||||
verilog_sources = [
|
|
||||||
os.path.join(rtl_dir, f"{dut}.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "lfsr.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_axis_rx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_cache.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "arbiter.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "priority_encoder.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_fifo.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
|
|
||||||
]
|
|
||||||
|
|
||||||
parameters = {}
|
|
||||||
|
|
||||||
# parameters['A'] = val
|
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
|
||||||
|
|
||||||
sim_build = os.path.join(tests_dir, "sim_build",
|
|
||||||
request.node.name.replace('[', '-').replace(']', ''))
|
|
||||||
|
|
||||||
cocotb_test.simulator.run(
|
|
||||||
python_search=[tests_dir],
|
|
||||||
verilog_sources=verilog_sources,
|
|
||||||
toplevel=toplevel,
|
|
||||||
module=module,
|
|
||||||
parameters=parameters,
|
|
||||||
sim_build=sim_build,
|
|
||||||
extra_env=extra_env,
|
|
||||||
)
|
|
@ -1,25 +0,0 @@
|
|||||||
# Targets
|
|
||||||
TARGETS:=
|
|
||||||
|
|
||||||
# Subdirectories
|
|
||||||
SUBDIRS = fpga
|
|
||||||
SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS))
|
|
||||||
|
|
||||||
# Rules
|
|
||||||
.PHONY: all
|
|
||||||
all: $(SUBDIRS) $(TARGETS)
|
|
||||||
|
|
||||||
.PHONY: $(SUBDIRS)
|
|
||||||
$(SUBDIRS):
|
|
||||||
cd $@ && $(MAKE)
|
|
||||||
|
|
||||||
.PHONY: $(SUBDIRS_CLEAN)
|
|
||||||
$(SUBDIRS_CLEAN):
|
|
||||||
cd $(@:.clean=) && $(MAKE) clean
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean: $(SUBDIRS_CLEAN)
|
|
||||||
-rm -rf $(TARGETS)
|
|
||||||
|
|
||||||
program:
|
|
||||||
#djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit
|
|
@ -1,30 +0,0 @@
|
|||||||
# Verilog Ethernet Alveo U280 Example Design
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
This example design targets the Xilinx Alveo U280 FPGA board.
|
|
||||||
|
|
||||||
The design by default listens to UDP port 1234 at IP address 192.168.1.128 and
|
|
||||||
will echo back any packets received. The design will also respond correctly
|
|
||||||
to ARP requests.
|
|
||||||
|
|
||||||
* FPGA: xcu280-fsvh2892-2L-e
|
|
||||||
* PHY: 10G BASE-R PHY IP core and internal GTY transceiver
|
|
||||||
|
|
||||||
## How to build
|
|
||||||
|
|
||||||
Run make to build. Ensure that the Xilinx Vivado toolchain components are
|
|
||||||
in PATH.
|
|
||||||
|
|
||||||
## How to test
|
|
||||||
|
|
||||||
Run make program to program the Alveo U280 board with Vivado. Then run
|
|
||||||
|
|
||||||
netcat -u 192.168.1.128 1234
|
|
||||||
|
|
||||||
to open a UDP connection to port 1234. Any text entered into netcat will be
|
|
||||||
echoed back after pressing enter.
|
|
||||||
|
|
||||||
It is also possible to use hping to test the design by running
|
|
||||||
|
|
||||||
hping 192.168.1.128 -2 -p 1234 -d 1024
|
|
@ -1,137 +0,0 @@
|
|||||||
###################################################################
|
|
||||||
#
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
FPGA_TOP ?= fpga
|
|
||||||
PROJECT ?= $(FPGA_TOP)
|
|
||||||
|
|
||||||
SYN_FILES_REL = $(foreach p,$(SYN_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
INC_FILES_REL = $(foreach p,$(INC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
XCI_FILES_REL = $(foreach p,$(XCI_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
IP_TCL_FILES_REL = $(foreach p,$(IP_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
CONFIG_TCL_FILES_REL = $(foreach p,$(CONFIG_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
|
|
||||||
ifdef XDC_FILES
|
|
||||||
XDC_FILES_REL = $(foreach p,$(XDC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
else
|
|
||||||
XDC_FILES_REL = $(PROJECT).xdc
|
|
||||||
endif
|
|
||||||
|
|
||||||
###################################################################
|
|
||||||
# Main Targets
|
|
||||||
#
|
|
||||||
# all: build everything
|
|
||||||
# clean: remove output files and project files
|
|
||||||
###################################################################
|
|
||||||
|
|
||||||
all: fpga
|
|
||||||
|
|
||||||
fpga: $(PROJECT).bit
|
|
||||||
|
|
||||||
vivado: $(PROJECT).xpr
|
|
||||||
vivado $(PROJECT).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 *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
|
|
||||||
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
|
|
||||||
|
|
||||||
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) $(PROJECT)" > $@
|
|
||||||
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
|
|
||||||
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
|
|
||||||
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) $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
|
|
||||||
echo "open_project -quiet $(PROJECT).xpr" > $@
|
|
||||||
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
|
|
||||||
|
|
||||||
$(PROJECT).xpr: create_project.tcl update_config.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
|
|
||||||
|
|
||||||
# synthesis run
|
|
||||||
$(PROJECT).runs/synth_1/$(PROJECT).dcp: create_project.tcl update_config.tcl $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) | $(PROJECT).xpr
|
|
||||||
echo "open_project $(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
|
|
||||||
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
|
|
||||||
echo "open_project $(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
|
|
||||||
echo "open_run impl_1" >> run_impl.tcl
|
|
||||||
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
|
|
||||||
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source run_impl.tcl
|
|
||||||
|
|
||||||
# bit file
|
|
||||||
$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
|
|
||||||
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
|
|
||||||
echo "open_run impl_1" >> generate_bit.tcl
|
|
||||||
echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
|
|
||||||
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
|
|
||||||
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
|
|
||||||
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
|
|
||||||
mkdir -p rev
|
|
||||||
COUNT=100; \
|
|
||||||
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
|
|
||||||
do COUNT=$$((COUNT+1)); done; \
|
|
||||||
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
|
|
||||||
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi
|
|
@ -1,76 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
set base_name {eth_xcvr_gt}
|
|
||||||
|
|
||||||
set preset {GTY-10GBASE-R}
|
|
||||||
|
|
||||||
set freerun_freq {125}
|
|
||||||
set line_rate {10.3125}
|
|
||||||
set refclk_freq {161.1328125}
|
|
||||||
set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}]
|
|
||||||
set user_data_width {64}
|
|
||||||
set int_data_width $user_data_width
|
|
||||||
set extra_ports [list]
|
|
||||||
set extra_pll_ports [list {qpll0lock_out}]
|
|
||||||
|
|
||||||
set config [dict create]
|
|
||||||
|
|
||||||
dict set config TX_LINE_RATE $line_rate
|
|
||||||
dict set config TX_REFCLK_FREQUENCY $refclk_freq
|
|
||||||
dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn
|
|
||||||
dict set config TX_USER_DATA_WIDTH $user_data_width
|
|
||||||
dict set config TX_INT_DATA_WIDTH $int_data_width
|
|
||||||
dict set config RX_LINE_RATE $line_rate
|
|
||||||
dict set config RX_REFCLK_FREQUENCY $refclk_freq
|
|
||||||
dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn
|
|
||||||
dict set config RX_USER_DATA_WIDTH $user_data_width
|
|
||||||
dict set config RX_INT_DATA_WIDTH $int_data_width
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
|
|
||||||
dict set config LOCATE_COMMON {CORE}
|
|
||||||
dict set config LOCATE_RESET_CONTROLLER {CORE}
|
|
||||||
dict set config LOCATE_TX_USER_CLOCKING {CORE}
|
|
||||||
dict set config LOCATE_RX_USER_CLOCKING {CORE}
|
|
||||||
dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE}
|
|
||||||
dict set config FREERUN_FREQUENCY $freerun_freq
|
|
||||||
dict set config DISABLE_LOC_XDC {1}
|
|
||||||
|
|
||||||
proc create_gtwizard_ip {name preset config} {
|
|
||||||
create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name
|
|
||||||
set ip [get_ips $name]
|
|
||||||
set_property CONFIG.preset $preset $ip
|
|
||||||
set config_list {}
|
|
||||||
dict for {name value} $config {
|
|
||||||
lappend config_list "CONFIG.${name}" $value
|
|
||||||
}
|
|
||||||
set_property -dict $config_list $ip
|
|
||||||
}
|
|
||||||
|
|
||||||
# variant with channel and common
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports]
|
|
||||||
dict set config LOCATE_COMMON {CORE}
|
|
||||||
|
|
||||||
create_gtwizard_ip "${base_name}_full" $preset $config
|
|
||||||
|
|
||||||
# variant with channel only
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
|
|
||||||
dict set config LOCATE_COMMON {EXAMPLE_DESIGN}
|
|
||||||
|
|
||||||
create_gtwizard_ip "${base_name}_channel" $preset $config
|
|
@ -1 +0,0 @@
|
|||||||
../../../../
|
|
@ -1,395 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2023 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transceiver and PHY quad wrapper
|
|
||||||
*/
|
|
||||||
module eth_xcvr_phy_quad_wrapper #
|
|
||||||
(
|
|
||||||
parameter COUNT = 4,
|
|
||||||
parameter DATA_WIDTH = 64,
|
|
||||||
parameter CTRL_WIDTH = (DATA_WIDTH/8),
|
|
||||||
parameter HDR_WIDTH = 2,
|
|
||||||
parameter PRBS31_ENABLE = 0,
|
|
||||||
parameter TX_SERDES_PIPELINE = 0,
|
|
||||||
parameter RX_SERDES_PIPELINE = 0,
|
|
||||||
parameter BITSLIP_HIGH_CYCLES = 1,
|
|
||||||
parameter BITSLIP_LOW_CYCLES = 8,
|
|
||||||
parameter COUNT_125US = 125000/6.4
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input wire xcvr_ctrl_clk,
|
|
||||||
input wire xcvr_ctrl_rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common
|
|
||||||
*/
|
|
||||||
output wire xcvr_gtpowergood_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL
|
|
||||||
*/
|
|
||||||
input wire xcvr_gtrefclk00_in,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Serial data
|
|
||||||
*/
|
|
||||||
output wire [COUNT-1:0] xcvr_txp,
|
|
||||||
output wire [COUNT-1:0] xcvr_txn,
|
|
||||||
input wire [COUNT-1:0] xcvr_rxp,
|
|
||||||
input wire [COUNT-1:0] xcvr_rxn,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PHY connections
|
|
||||||
*/
|
|
||||||
output wire phy_1_tx_clk,
|
|
||||||
output wire phy_1_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_1_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_1_xgmii_txc,
|
|
||||||
output wire phy_1_rx_clk,
|
|
||||||
output wire phy_1_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_1_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_1_xgmii_rxc,
|
|
||||||
output wire phy_1_tx_bad_block,
|
|
||||||
output wire [6:0] phy_1_rx_error_count,
|
|
||||||
output wire phy_1_rx_bad_block,
|
|
||||||
output wire phy_1_rx_sequence_error,
|
|
||||||
output wire phy_1_rx_block_lock,
|
|
||||||
output wire phy_1_rx_high_ber,
|
|
||||||
output wire phy_1_rx_status,
|
|
||||||
input wire phy_1_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_1_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_2_tx_clk,
|
|
||||||
output wire phy_2_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_2_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_2_xgmii_txc,
|
|
||||||
output wire phy_2_rx_clk,
|
|
||||||
output wire phy_2_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_2_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_2_xgmii_rxc,
|
|
||||||
output wire phy_2_tx_bad_block,
|
|
||||||
output wire [6:0] phy_2_rx_error_count,
|
|
||||||
output wire phy_2_rx_bad_block,
|
|
||||||
output wire phy_2_rx_sequence_error,
|
|
||||||
output wire phy_2_rx_block_lock,
|
|
||||||
output wire phy_2_rx_high_ber,
|
|
||||||
output wire phy_2_rx_status,
|
|
||||||
input wire phy_2_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_2_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_3_tx_clk,
|
|
||||||
output wire phy_3_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_3_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_3_xgmii_txc,
|
|
||||||
output wire phy_3_rx_clk,
|
|
||||||
output wire phy_3_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_3_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_3_xgmii_rxc,
|
|
||||||
output wire phy_3_tx_bad_block,
|
|
||||||
output wire [6:0] phy_3_rx_error_count,
|
|
||||||
output wire phy_3_rx_bad_block,
|
|
||||||
output wire phy_3_rx_sequence_error,
|
|
||||||
output wire phy_3_rx_block_lock,
|
|
||||||
output wire phy_3_rx_high_ber,
|
|
||||||
output wire phy_3_rx_status,
|
|
||||||
input wire phy_3_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_3_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_4_tx_clk,
|
|
||||||
output wire phy_4_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_4_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_4_xgmii_txc,
|
|
||||||
output wire phy_4_rx_clk,
|
|
||||||
output wire phy_4_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_4_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_4_xgmii_rxc,
|
|
||||||
output wire phy_4_tx_bad_block,
|
|
||||||
output wire [6:0] phy_4_rx_error_count,
|
|
||||||
output wire phy_4_rx_bad_block,
|
|
||||||
output wire phy_4_rx_sequence_error,
|
|
||||||
output wire phy_4_rx_block_lock,
|
|
||||||
output wire phy_4_rx_high_ber,
|
|
||||||
output wire phy_4_rx_status,
|
|
||||||
input wire phy_4_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_4_cfg_rx_prbs31_enable
|
|
||||||
);
|
|
||||||
|
|
||||||
generate
|
|
||||||
|
|
||||||
wire xcvr_qpll0lock;
|
|
||||||
wire xcvr_qpll0clk;
|
|
||||||
wire xcvr_qpll0refclk;
|
|
||||||
|
|
||||||
if (COUNT > 0) begin : phy1
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(1),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_1 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(xcvr_gtrefclk00_in),
|
|
||||||
.xcvr_qpll0lock_out(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_out(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_out(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(1'b0),
|
|
||||||
.xcvr_qpll0clk_in(1'b0),
|
|
||||||
.xcvr_qpll0refclk_in(1'b0),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[0]),
|
|
||||||
.xcvr_txn(xcvr_txn[0]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[0]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[0]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_1_tx_clk),
|
|
||||||
.phy_tx_rst(phy_1_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_1_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_1_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_1_rx_clk),
|
|
||||||
.phy_rx_rst(phy_1_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_1_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_1_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_1_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_1_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_1_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_1_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_1_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_1_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_1_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_1_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_1_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 1) begin : phy2
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_2 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[1]),
|
|
||||||
.xcvr_txn(xcvr_txn[1]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[1]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[1]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_2_tx_clk),
|
|
||||||
.phy_tx_rst(phy_2_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_2_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_2_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_2_rx_clk),
|
|
||||||
.phy_rx_rst(phy_2_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_2_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_2_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_2_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_2_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_2_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_2_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_2_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_2_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_2_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_2_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_2_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 2) begin : phy3
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_3 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[2]),
|
|
||||||
.xcvr_txn(xcvr_txn[2]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[2]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[2]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_3_tx_clk),
|
|
||||||
.phy_tx_rst(phy_3_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_3_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_3_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_3_rx_clk),
|
|
||||||
.phy_rx_rst(phy_3_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_3_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_3_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_3_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_3_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_3_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_3_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_3_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_3_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_3_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_3_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_3_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 3) begin : phy4
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_4 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[3]),
|
|
||||||
.xcvr_txn(xcvr_txn[3]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[3]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[3]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_4_tx_clk),
|
|
||||||
.phy_tx_rst(phy_4_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_4_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_4_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_4_rx_clk),
|
|
||||||
.phy_rx_rst(phy_4_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_4_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_4_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_4_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_4_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_4_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_4_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_4_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_4_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_4_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_4_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_4_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,307 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2021-2023 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transceiver and PHY wrapper
|
|
||||||
*/
|
|
||||||
module eth_xcvr_phy_wrapper #
|
|
||||||
(
|
|
||||||
parameter HAS_COMMON = 1,
|
|
||||||
parameter DATA_WIDTH = 64,
|
|
||||||
parameter CTRL_WIDTH = (DATA_WIDTH/8),
|
|
||||||
parameter HDR_WIDTH = 2,
|
|
||||||
parameter PRBS31_ENABLE = 0,
|
|
||||||
parameter TX_SERDES_PIPELINE = 0,
|
|
||||||
parameter RX_SERDES_PIPELINE = 0,
|
|
||||||
parameter BITSLIP_HIGH_CYCLES = 1,
|
|
||||||
parameter BITSLIP_LOW_CYCLES = 8,
|
|
||||||
parameter COUNT_125US = 125000/6.4
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input wire xcvr_ctrl_clk,
|
|
||||||
input wire xcvr_ctrl_rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common
|
|
||||||
*/
|
|
||||||
output wire xcvr_gtpowergood_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL out
|
|
||||||
*/
|
|
||||||
input wire xcvr_gtrefclk00_in,
|
|
||||||
output wire xcvr_qpll0lock_out,
|
|
||||||
output wire xcvr_qpll0clk_out,
|
|
||||||
output wire xcvr_qpll0refclk_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL in
|
|
||||||
*/
|
|
||||||
input wire xcvr_qpll0lock_in,
|
|
||||||
output wire xcvr_qpll0reset_out,
|
|
||||||
input wire xcvr_qpll0clk_in,
|
|
||||||
input wire xcvr_qpll0refclk_in,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Serial data
|
|
||||||
*/
|
|
||||||
output wire xcvr_txp,
|
|
||||||
output wire xcvr_txn,
|
|
||||||
input wire xcvr_rxp,
|
|
||||||
input wire xcvr_rxn,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PHY connections
|
|
||||||
*/
|
|
||||||
output wire phy_tx_clk,
|
|
||||||
output wire phy_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_xgmii_txc,
|
|
||||||
output wire phy_rx_clk,
|
|
||||||
output wire phy_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_xgmii_rxc,
|
|
||||||
output wire phy_tx_bad_block,
|
|
||||||
output wire [6:0] phy_rx_error_count,
|
|
||||||
output wire phy_rx_bad_block,
|
|
||||||
output wire phy_rx_sequence_error,
|
|
||||||
output wire phy_rx_block_lock,
|
|
||||||
output wire phy_rx_high_ber,
|
|
||||||
output wire phy_rx_status,
|
|
||||||
input wire phy_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_cfg_rx_prbs31_enable
|
|
||||||
);
|
|
||||||
|
|
||||||
wire phy_rx_reset_req;
|
|
||||||
|
|
||||||
wire gt_reset_tx_datapath = 1'b0;
|
|
||||||
wire gt_reset_rx_datapath = phy_rx_reset_req;
|
|
||||||
|
|
||||||
wire gt_reset_tx_done;
|
|
||||||
wire gt_reset_rx_done;
|
|
||||||
|
|
||||||
wire [5:0] gt_txheader;
|
|
||||||
wire [63:0] gt_txdata;
|
|
||||||
wire gt_rxgearboxslip;
|
|
||||||
wire [5:0] gt_rxheader;
|
|
||||||
wire [1:0] gt_rxheadervalid;
|
|
||||||
wire [63:0] gt_rxdata;
|
|
||||||
wire [1:0] gt_rxdatavalid;
|
|
||||||
|
|
||||||
generate
|
|
||||||
|
|
||||||
if (HAS_COMMON) begin : xcvr
|
|
||||||
|
|
||||||
eth_xcvr_gt_full
|
|
||||||
eth_xcvr_gt_full_inst (
|
|
||||||
// Common
|
|
||||||
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
|
|
||||||
.gtwiz_reset_all_in(xcvr_ctrl_rst),
|
|
||||||
.gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL
|
|
||||||
.gtrefclk00_in(xcvr_gtrefclk00_in),
|
|
||||||
.qpll0lock_out(xcvr_qpll0lock_out),
|
|
||||||
.qpll0outclk_out(xcvr_qpll0clk_out),
|
|
||||||
.qpll0outrefclk_out(xcvr_qpll0refclk_out),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.gtytxp_out(xcvr_txp),
|
|
||||||
.gtytxn_out(xcvr_txn),
|
|
||||||
.gtyrxp_in(xcvr_rxp),
|
|
||||||
.gtyrxn_in(xcvr_rxn),
|
|
||||||
|
|
||||||
// Transmit
|
|
||||||
.gtwiz_userclk_tx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_tx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
|
|
||||||
.gtwiz_userclk_tx_active_out(),
|
|
||||||
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
|
|
||||||
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
|
|
||||||
.txpmaresetdone_out(),
|
|
||||||
.txprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.gtwiz_userdata_tx_in(gt_txdata),
|
|
||||||
.txheader_in(gt_txheader),
|
|
||||||
.txsequence_in(7'b0),
|
|
||||||
|
|
||||||
// Receive
|
|
||||||
.gtwiz_userclk_rx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_rx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
|
|
||||||
.gtwiz_userclk_rx_active_out(),
|
|
||||||
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
|
|
||||||
.gtwiz_reset_rx_cdr_stable_out(),
|
|
||||||
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
|
|
||||||
.rxpmaresetdone_out(),
|
|
||||||
.rxprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.rxgearboxslip_in(gt_rxgearboxslip),
|
|
||||||
.gtwiz_userdata_rx_out(gt_rxdata),
|
|
||||||
.rxdatavalid_out(gt_rxdatavalid),
|
|
||||||
.rxheader_out(gt_rxheader),
|
|
||||||
.rxheadervalid_out(gt_rxheadervalid),
|
|
||||||
.rxstartofseq_out()
|
|
||||||
);
|
|
||||||
|
|
||||||
assign xcvr_qpll0reset_out = 1'b0;
|
|
||||||
|
|
||||||
end else begin : xcvr
|
|
||||||
|
|
||||||
eth_xcvr_gt_channel
|
|
||||||
eth_xcvr_gt_channel_inst (
|
|
||||||
// Common
|
|
||||||
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
|
|
||||||
.gtwiz_reset_all_in(xcvr_ctrl_rst),
|
|
||||||
.gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL
|
|
||||||
.gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in),
|
|
||||||
.gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out),
|
|
||||||
.qpll0clk_in(xcvr_qpll0clk_in),
|
|
||||||
.qpll0refclk_in(xcvr_qpll0refclk_in),
|
|
||||||
.qpll1clk_in(1'b0),
|
|
||||||
.qpll1refclk_in(1'b0),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.gtytxp_out(xcvr_txp),
|
|
||||||
.gtytxn_out(xcvr_txn),
|
|
||||||
.gtyrxp_in(xcvr_rxp),
|
|
||||||
.gtyrxn_in(xcvr_rxn),
|
|
||||||
|
|
||||||
// Transmit
|
|
||||||
.gtwiz_userclk_tx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_tx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
|
|
||||||
.gtwiz_userclk_tx_active_out(),
|
|
||||||
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
|
|
||||||
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
|
|
||||||
.txpmaresetdone_out(),
|
|
||||||
.txprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.gtwiz_userdata_tx_in(gt_txdata),
|
|
||||||
.txheader_in(gt_txheader),
|
|
||||||
.txsequence_in(7'b0),
|
|
||||||
|
|
||||||
// Receive
|
|
||||||
.gtwiz_userclk_rx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_rx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
|
|
||||||
.gtwiz_userclk_rx_active_out(),
|
|
||||||
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
|
|
||||||
.gtwiz_reset_rx_cdr_stable_out(),
|
|
||||||
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
|
|
||||||
.rxpmaresetdone_out(),
|
|
||||||
.rxprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.rxgearboxslip_in(gt_rxgearboxslip),
|
|
||||||
.gtwiz_userdata_rx_out(gt_rxdata),
|
|
||||||
.rxdatavalid_out(gt_rxdatavalid),
|
|
||||||
.rxheader_out(gt_rxheader),
|
|
||||||
.rxheadervalid_out(gt_rxheadervalid),
|
|
||||||
.rxstartofseq_out()
|
|
||||||
);
|
|
||||||
|
|
||||||
assign xcvr_qpll0lock_out = 1'b0;
|
|
||||||
assign xcvr_qpll0clk_out = 1'b0;
|
|
||||||
assign xcvr_qpll0refclk_out = 1'b0;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
sync_reset #(
|
|
||||||
.N(4)
|
|
||||||
)
|
|
||||||
tx_reset_sync_inst (
|
|
||||||
.clk(phy_tx_clk),
|
|
||||||
.rst(!gt_reset_tx_done),
|
|
||||||
.out(phy_tx_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
sync_reset #(
|
|
||||||
.N(4)
|
|
||||||
)
|
|
||||||
rx_reset_sync_inst (
|
|
||||||
.clk(phy_rx_clk),
|
|
||||||
.rst(!gt_reset_rx_done),
|
|
||||||
.out(phy_rx_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_phy_10g #(
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.BIT_REVERSE(1),
|
|
||||||
.SCRAMBLER_DISABLE(0),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
phy_inst (
|
|
||||||
.tx_clk(phy_tx_clk),
|
|
||||||
.tx_rst(phy_tx_rst),
|
|
||||||
.rx_clk(phy_rx_clk),
|
|
||||||
.rx_rst(phy_rx_rst),
|
|
||||||
.xgmii_txd(phy_xgmii_txd),
|
|
||||||
.xgmii_txc(phy_xgmii_txc),
|
|
||||||
.xgmii_rxd(phy_xgmii_rxd),
|
|
||||||
.xgmii_rxc(phy_xgmii_rxc),
|
|
||||||
.serdes_tx_data(gt_txdata),
|
|
||||||
.serdes_tx_hdr(gt_txheader),
|
|
||||||
.serdes_rx_data(gt_rxdata),
|
|
||||||
.serdes_rx_hdr(gt_rxheader),
|
|
||||||
.serdes_rx_bitslip(gt_rxgearboxslip),
|
|
||||||
.serdes_rx_reset_req(phy_rx_reset_req),
|
|
||||||
.tx_bad_block(phy_tx_bad_block),
|
|
||||||
.rx_error_count(phy_rx_error_count),
|
|
||||||
.rx_bad_block(phy_rx_bad_block),
|
|
||||||
.rx_sequence_error(phy_rx_sequence_error),
|
|
||||||
.rx_block_lock(phy_rx_block_lock),
|
|
||||||
.rx_high_ber(phy_rx_high_ber),
|
|
||||||
.rx_status(phy_rx_status),
|
|
||||||
.cfg_tx_prbs31_enable(phy_cfg_tx_prbs31_enable),
|
|
||||||
.cfg_rx_prbs31_enable(phy_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,655 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014-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 core logic
|
|
||||||
*/
|
|
||||||
module fpga_core #
|
|
||||||
(
|
|
||||||
parameter TARGET = "XILINX"
|
|
||||||
)
|
|
||||||
(
|
|
||||||
/*
|
|
||||||
* Clock: 156.25MHz
|
|
||||||
* Synchronous reset
|
|
||||||
*/
|
|
||||||
input wire clk,
|
|
||||||
input wire rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ethernet: QSFP28
|
|
||||||
*/
|
|
||||||
input wire qsfp0_tx_clk_1,
|
|
||||||
input wire qsfp0_tx_rst_1,
|
|
||||||
output wire [63:0] qsfp0_txd_1,
|
|
||||||
output wire [7:0] qsfp0_txc_1,
|
|
||||||
input wire qsfp0_rx_clk_1,
|
|
||||||
input wire qsfp0_rx_rst_1,
|
|
||||||
input wire [63:0] qsfp0_rxd_1,
|
|
||||||
input wire [7:0] qsfp0_rxc_1,
|
|
||||||
input wire qsfp0_tx_clk_2,
|
|
||||||
input wire qsfp0_tx_rst_2,
|
|
||||||
output wire [63:0] qsfp0_txd_2,
|
|
||||||
output wire [7:0] qsfp0_txc_2,
|
|
||||||
input wire qsfp0_rx_clk_2,
|
|
||||||
input wire qsfp0_rx_rst_2,
|
|
||||||
input wire [63:0] qsfp0_rxd_2,
|
|
||||||
input wire [7:0] qsfp0_rxc_2,
|
|
||||||
input wire qsfp0_tx_clk_3,
|
|
||||||
input wire qsfp0_tx_rst_3,
|
|
||||||
output wire [63:0] qsfp0_txd_3,
|
|
||||||
output wire [7:0] qsfp0_txc_3,
|
|
||||||
input wire qsfp0_rx_clk_3,
|
|
||||||
input wire qsfp0_rx_rst_3,
|
|
||||||
input wire [63:0] qsfp0_rxd_3,
|
|
||||||
input wire [7:0] qsfp0_rxc_3,
|
|
||||||
input wire qsfp0_tx_clk_4,
|
|
||||||
input wire qsfp0_tx_rst_4,
|
|
||||||
output wire [63:0] qsfp0_txd_4,
|
|
||||||
output wire [7:0] qsfp0_txc_4,
|
|
||||||
input wire qsfp0_rx_clk_4,
|
|
||||||
input wire qsfp0_rx_rst_4,
|
|
||||||
input wire [63:0] qsfp0_rxd_4,
|
|
||||||
input wire [7:0] qsfp0_rxc_4,
|
|
||||||
input wire qsfp1_tx_clk_1,
|
|
||||||
input wire qsfp1_tx_rst_1,
|
|
||||||
output wire [63:0] qsfp1_txd_1,
|
|
||||||
output wire [7:0] qsfp1_txc_1,
|
|
||||||
input wire qsfp1_rx_clk_1,
|
|
||||||
input wire qsfp1_rx_rst_1,
|
|
||||||
input wire [63:0] qsfp1_rxd_1,
|
|
||||||
input wire [7:0] qsfp1_rxc_1,
|
|
||||||
input wire qsfp1_tx_clk_2,
|
|
||||||
input wire qsfp1_tx_rst_2,
|
|
||||||
output wire [63:0] qsfp1_txd_2,
|
|
||||||
output wire [7:0] qsfp1_txc_2,
|
|
||||||
input wire qsfp1_rx_clk_2,
|
|
||||||
input wire qsfp1_rx_rst_2,
|
|
||||||
input wire [63:0] qsfp1_rxd_2,
|
|
||||||
input wire [7:0] qsfp1_rxc_2,
|
|
||||||
input wire qsfp1_tx_clk_3,
|
|
||||||
input wire qsfp1_tx_rst_3,
|
|
||||||
output wire [63:0] qsfp1_txd_3,
|
|
||||||
output wire [7:0] qsfp1_txc_3,
|
|
||||||
input wire qsfp1_rx_clk_3,
|
|
||||||
input wire qsfp1_rx_rst_3,
|
|
||||||
input wire [63:0] qsfp1_rxd_3,
|
|
||||||
input wire [7:0] qsfp1_rxc_3,
|
|
||||||
input wire qsfp1_tx_clk_4,
|
|
||||||
input wire qsfp1_tx_rst_4,
|
|
||||||
output wire [63:0] qsfp1_txd_4,
|
|
||||||
output wire [7:0] qsfp1_txc_4,
|
|
||||||
input wire qsfp1_rx_clk_4,
|
|
||||||
input wire qsfp1_rx_rst_4,
|
|
||||||
input wire [63:0] qsfp1_rxd_4,
|
|
||||||
input wire [7:0] qsfp1_rxc_4
|
|
||||||
);
|
|
||||||
|
|
||||||
// AXI between MAC and Ethernet modules
|
|
||||||
wire [63:0] rx_axis_tdata;
|
|
||||||
wire [7:0] rx_axis_tkeep;
|
|
||||||
wire rx_axis_tvalid;
|
|
||||||
wire rx_axis_tready;
|
|
||||||
wire rx_axis_tlast;
|
|
||||||
wire rx_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] tx_axis_tdata;
|
|
||||||
wire [7:0] tx_axis_tkeep;
|
|
||||||
wire tx_axis_tvalid;
|
|
||||||
wire tx_axis_tready;
|
|
||||||
wire tx_axis_tlast;
|
|
||||||
wire tx_axis_tuser;
|
|
||||||
|
|
||||||
// Ethernet frame between Ethernet modules and UDP stack
|
|
||||||
wire rx_eth_hdr_ready;
|
|
||||||
wire rx_eth_hdr_valid;
|
|
||||||
wire [47:0] rx_eth_dest_mac;
|
|
||||||
wire [47:0] rx_eth_src_mac;
|
|
||||||
wire [15:0] rx_eth_type;
|
|
||||||
wire [63:0] rx_eth_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_eth_payload_axis_tkeep;
|
|
||||||
wire rx_eth_payload_axis_tvalid;
|
|
||||||
wire rx_eth_payload_axis_tready;
|
|
||||||
wire rx_eth_payload_axis_tlast;
|
|
||||||
wire rx_eth_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_eth_hdr_ready;
|
|
||||||
wire tx_eth_hdr_valid;
|
|
||||||
wire [47:0] tx_eth_dest_mac;
|
|
||||||
wire [47:0] tx_eth_src_mac;
|
|
||||||
wire [15:0] tx_eth_type;
|
|
||||||
wire [63:0] tx_eth_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_eth_payload_axis_tkeep;
|
|
||||||
wire tx_eth_payload_axis_tvalid;
|
|
||||||
wire tx_eth_payload_axis_tready;
|
|
||||||
wire tx_eth_payload_axis_tlast;
|
|
||||||
wire tx_eth_payload_axis_tuser;
|
|
||||||
|
|
||||||
// IP frame connections
|
|
||||||
wire rx_ip_hdr_valid;
|
|
||||||
wire rx_ip_hdr_ready;
|
|
||||||
wire [47:0] rx_ip_eth_dest_mac;
|
|
||||||
wire [47:0] rx_ip_eth_src_mac;
|
|
||||||
wire [15:0] rx_ip_eth_type;
|
|
||||||
wire [3:0] rx_ip_version;
|
|
||||||
wire [3:0] rx_ip_ihl;
|
|
||||||
wire [5:0] rx_ip_dscp;
|
|
||||||
wire [1:0] rx_ip_ecn;
|
|
||||||
wire [15:0] rx_ip_length;
|
|
||||||
wire [15:0] rx_ip_identification;
|
|
||||||
wire [2:0] rx_ip_flags;
|
|
||||||
wire [12:0] rx_ip_fragment_offset;
|
|
||||||
wire [7:0] rx_ip_ttl;
|
|
||||||
wire [7:0] rx_ip_protocol;
|
|
||||||
wire [15:0] rx_ip_header_checksum;
|
|
||||||
wire [31:0] rx_ip_source_ip;
|
|
||||||
wire [31:0] rx_ip_dest_ip;
|
|
||||||
wire [63:0] rx_ip_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_ip_payload_axis_tkeep;
|
|
||||||
wire rx_ip_payload_axis_tvalid;
|
|
||||||
wire rx_ip_payload_axis_tready;
|
|
||||||
wire rx_ip_payload_axis_tlast;
|
|
||||||
wire rx_ip_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_ip_hdr_valid;
|
|
||||||
wire tx_ip_hdr_ready;
|
|
||||||
wire [5:0] tx_ip_dscp;
|
|
||||||
wire [1:0] tx_ip_ecn;
|
|
||||||
wire [15:0] tx_ip_length;
|
|
||||||
wire [7:0] tx_ip_ttl;
|
|
||||||
wire [7:0] tx_ip_protocol;
|
|
||||||
wire [31:0] tx_ip_source_ip;
|
|
||||||
wire [31:0] tx_ip_dest_ip;
|
|
||||||
wire [63:0] tx_ip_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_ip_payload_axis_tkeep;
|
|
||||||
wire tx_ip_payload_axis_tvalid;
|
|
||||||
wire tx_ip_payload_axis_tready;
|
|
||||||
wire tx_ip_payload_axis_tlast;
|
|
||||||
wire tx_ip_payload_axis_tuser;
|
|
||||||
|
|
||||||
// UDP frame connections
|
|
||||||
wire rx_udp_hdr_valid;
|
|
||||||
wire rx_udp_hdr_ready;
|
|
||||||
wire [47:0] rx_udp_eth_dest_mac;
|
|
||||||
wire [47:0] rx_udp_eth_src_mac;
|
|
||||||
wire [15:0] rx_udp_eth_type;
|
|
||||||
wire [3:0] rx_udp_ip_version;
|
|
||||||
wire [3:0] rx_udp_ip_ihl;
|
|
||||||
wire [5:0] rx_udp_ip_dscp;
|
|
||||||
wire [1:0] rx_udp_ip_ecn;
|
|
||||||
wire [15:0] rx_udp_ip_length;
|
|
||||||
wire [15:0] rx_udp_ip_identification;
|
|
||||||
wire [2:0] rx_udp_ip_flags;
|
|
||||||
wire [12:0] rx_udp_ip_fragment_offset;
|
|
||||||
wire [7:0] rx_udp_ip_ttl;
|
|
||||||
wire [7:0] rx_udp_ip_protocol;
|
|
||||||
wire [15:0] rx_udp_ip_header_checksum;
|
|
||||||
wire [31:0] rx_udp_ip_source_ip;
|
|
||||||
wire [31:0] rx_udp_ip_dest_ip;
|
|
||||||
wire [15:0] rx_udp_source_port;
|
|
||||||
wire [15:0] rx_udp_dest_port;
|
|
||||||
wire [15:0] rx_udp_length;
|
|
||||||
wire [15:0] rx_udp_checksum;
|
|
||||||
wire [63:0] rx_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_udp_payload_axis_tkeep;
|
|
||||||
wire rx_udp_payload_axis_tvalid;
|
|
||||||
wire rx_udp_payload_axis_tready;
|
|
||||||
wire rx_udp_payload_axis_tlast;
|
|
||||||
wire rx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire tx_udp_hdr_valid;
|
|
||||||
wire tx_udp_hdr_ready;
|
|
||||||
wire [5:0] tx_udp_ip_dscp;
|
|
||||||
wire [1:0] tx_udp_ip_ecn;
|
|
||||||
wire [7:0] tx_udp_ip_ttl;
|
|
||||||
wire [31:0] tx_udp_ip_source_ip;
|
|
||||||
wire [31:0] tx_udp_ip_dest_ip;
|
|
||||||
wire [15:0] tx_udp_source_port;
|
|
||||||
wire [15:0] tx_udp_dest_port;
|
|
||||||
wire [15:0] tx_udp_length;
|
|
||||||
wire [15:0] tx_udp_checksum;
|
|
||||||
wire [63:0] tx_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_udp_payload_axis_tkeep;
|
|
||||||
wire tx_udp_payload_axis_tvalid;
|
|
||||||
wire tx_udp_payload_axis_tready;
|
|
||||||
wire tx_udp_payload_axis_tlast;
|
|
||||||
wire tx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] rx_fifo_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] rx_fifo_udp_payload_axis_tkeep;
|
|
||||||
wire rx_fifo_udp_payload_axis_tvalid;
|
|
||||||
wire rx_fifo_udp_payload_axis_tready;
|
|
||||||
wire rx_fifo_udp_payload_axis_tlast;
|
|
||||||
wire rx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
wire [63:0] tx_fifo_udp_payload_axis_tdata;
|
|
||||||
wire [7:0] tx_fifo_udp_payload_axis_tkeep;
|
|
||||||
wire tx_fifo_udp_payload_axis_tvalid;
|
|
||||||
wire tx_fifo_udp_payload_axis_tready;
|
|
||||||
wire tx_fifo_udp_payload_axis_tlast;
|
|
||||||
wire tx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
// Configuration
|
|
||||||
wire [47:0] local_mac = 48'h02_00_00_00_00_00;
|
|
||||||
wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128};
|
|
||||||
wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1};
|
|
||||||
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
|
|
||||||
|
|
||||||
// IP ports not used
|
|
||||||
assign rx_ip_hdr_ready = 1;
|
|
||||||
assign rx_ip_payload_axis_tready = 1;
|
|
||||||
|
|
||||||
assign tx_ip_hdr_valid = 0;
|
|
||||||
assign tx_ip_dscp = 0;
|
|
||||||
assign tx_ip_ecn = 0;
|
|
||||||
assign tx_ip_length = 0;
|
|
||||||
assign tx_ip_ttl = 0;
|
|
||||||
assign tx_ip_protocol = 0;
|
|
||||||
assign tx_ip_source_ip = 0;
|
|
||||||
assign tx_ip_dest_ip = 0;
|
|
||||||
assign tx_ip_payload_axis_tdata = 0;
|
|
||||||
assign tx_ip_payload_axis_tkeep = 0;
|
|
||||||
assign tx_ip_payload_axis_tvalid = 0;
|
|
||||||
assign tx_ip_payload_axis_tlast = 0;
|
|
||||||
assign tx_ip_payload_axis_tuser = 0;
|
|
||||||
|
|
||||||
// Loop back UDP
|
|
||||||
wire match_cond = rx_udp_dest_port == 1234;
|
|
||||||
wire no_match = !match_cond;
|
|
||||||
|
|
||||||
reg match_cond_reg = 0;
|
|
||||||
reg no_match_reg = 0;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (rst) begin
|
|
||||||
match_cond_reg <= 0;
|
|
||||||
no_match_reg <= 0;
|
|
||||||
end else begin
|
|
||||||
if (rx_udp_payload_axis_tvalid) begin
|
|
||||||
if ((!match_cond_reg && !no_match_reg) ||
|
|
||||||
(rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
|
|
||||||
match_cond_reg <= match_cond;
|
|
||||||
no_match_reg <= no_match;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
match_cond_reg <= 0;
|
|
||||||
no_match_reg <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
|
|
||||||
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
|
|
||||||
assign tx_udp_ip_dscp = 0;
|
|
||||||
assign tx_udp_ip_ecn = 0;
|
|
||||||
assign tx_udp_ip_ttl = 64;
|
|
||||||
assign tx_udp_ip_source_ip = local_ip;
|
|
||||||
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
|
|
||||||
assign tx_udp_source_port = rx_udp_dest_port;
|
|
||||||
assign tx_udp_dest_port = rx_udp_source_port;
|
|
||||||
assign tx_udp_length = rx_udp_length;
|
|
||||||
assign tx_udp_checksum = 0;
|
|
||||||
|
|
||||||
assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
|
|
||||||
assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep;
|
|
||||||
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
|
|
||||||
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
|
|
||||||
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
|
|
||||||
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
|
|
||||||
assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep;
|
|
||||||
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
|
|
||||||
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
|
|
||||||
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
|
|
||||||
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;
|
|
||||||
|
|
||||||
// Place first payload byte onto LEDs
|
|
||||||
reg valid_last = 0;
|
|
||||||
reg [7:0] led_reg = 0;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (rst) begin
|
|
||||||
led_reg <= 0;
|
|
||||||
end else begin
|
|
||||||
valid_last <= tx_udp_payload_axis_tvalid;
|
|
||||||
if (tx_udp_payload_axis_tvalid && !valid_last) begin
|
|
||||||
led_reg <= tx_udp_payload_axis_tdata;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign qsfp0_txd_2 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_2 = 8'hff;
|
|
||||||
assign qsfp0_txd_3 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_3 = 8'hff;
|
|
||||||
assign qsfp0_txd_4 = 64'h0707070707070707;
|
|
||||||
assign qsfp0_txc_4 = 8'hff;
|
|
||||||
|
|
||||||
assign qsfp1_txd_1 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_1 = 8'hff;
|
|
||||||
assign qsfp1_txd_2 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_2 = 8'hff;
|
|
||||||
assign qsfp1_txd_3 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_3 = 8'hff;
|
|
||||||
assign qsfp1_txd_4 = 64'h0707070707070707;
|
|
||||||
assign qsfp1_txc_4 = 8'hff;
|
|
||||||
|
|
||||||
eth_mac_10g_fifo #(
|
|
||||||
.ENABLE_PADDING(1),
|
|
||||||
.ENABLE_DIC(1),
|
|
||||||
.MIN_FRAME_LENGTH(64),
|
|
||||||
.TX_FIFO_DEPTH(4096),
|
|
||||||
.TX_FRAME_FIFO(1),
|
|
||||||
.RX_FIFO_DEPTH(4096),
|
|
||||||
.RX_FRAME_FIFO(1)
|
|
||||||
)
|
|
||||||
eth_mac_10g_fifo_inst (
|
|
||||||
.rx_clk(qsfp0_rx_clk_1),
|
|
||||||
.rx_rst(qsfp0_rx_rst_1),
|
|
||||||
.tx_clk(qsfp0_tx_clk_1),
|
|
||||||
.tx_rst(qsfp0_tx_rst_1),
|
|
||||||
.logic_clk(clk),
|
|
||||||
.logic_rst(rst),
|
|
||||||
|
|
||||||
.tx_axis_tdata(tx_axis_tdata),
|
|
||||||
.tx_axis_tkeep(tx_axis_tkeep),
|
|
||||||
.tx_axis_tvalid(tx_axis_tvalid),
|
|
||||||
.tx_axis_tready(tx_axis_tready),
|
|
||||||
.tx_axis_tlast(tx_axis_tlast),
|
|
||||||
.tx_axis_tuser(tx_axis_tuser),
|
|
||||||
|
|
||||||
.rx_axis_tdata(rx_axis_tdata),
|
|
||||||
.rx_axis_tkeep(rx_axis_tkeep),
|
|
||||||
.rx_axis_tvalid(rx_axis_tvalid),
|
|
||||||
.rx_axis_tready(rx_axis_tready),
|
|
||||||
.rx_axis_tlast(rx_axis_tlast),
|
|
||||||
.rx_axis_tuser(rx_axis_tuser),
|
|
||||||
|
|
||||||
.xgmii_rxd(qsfp0_rxd_1),
|
|
||||||
.xgmii_rxc(qsfp0_rxc_1),
|
|
||||||
.xgmii_txd(qsfp0_txd_1),
|
|
||||||
.xgmii_txc(qsfp0_txc_1),
|
|
||||||
|
|
||||||
.tx_fifo_overflow(),
|
|
||||||
.tx_fifo_bad_frame(),
|
|
||||||
.tx_fifo_good_frame(),
|
|
||||||
.rx_error_bad_frame(),
|
|
||||||
.rx_error_bad_fcs(),
|
|
||||||
.rx_fifo_overflow(),
|
|
||||||
.rx_fifo_bad_frame(),
|
|
||||||
.rx_fifo_good_frame(),
|
|
||||||
|
|
||||||
.cfg_ifg(8'd12),
|
|
||||||
.cfg_tx_enable(1'b1),
|
|
||||||
.cfg_rx_enable(1'b1)
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_axis_rx #(
|
|
||||||
.DATA_WIDTH(64)
|
|
||||||
)
|
|
||||||
eth_axis_rx_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// AXI input
|
|
||||||
.s_axis_tdata(rx_axis_tdata),
|
|
||||||
.s_axis_tkeep(rx_axis_tkeep),
|
|
||||||
.s_axis_tvalid(rx_axis_tvalid),
|
|
||||||
.s_axis_tready(rx_axis_tready),
|
|
||||||
.s_axis_tlast(rx_axis_tlast),
|
|
||||||
.s_axis_tuser(rx_axis_tuser),
|
|
||||||
// Ethernet frame output
|
|
||||||
.m_eth_hdr_valid(rx_eth_hdr_valid),
|
|
||||||
.m_eth_hdr_ready(rx_eth_hdr_ready),
|
|
||||||
.m_eth_dest_mac(rx_eth_dest_mac),
|
|
||||||
.m_eth_src_mac(rx_eth_src_mac),
|
|
||||||
.m_eth_type(rx_eth_type),
|
|
||||||
.m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
|
||||||
.m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
|
|
||||||
.m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
|
||||||
.m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
|
||||||
.m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
|
||||||
.m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.busy(),
|
|
||||||
.error_header_early_termination()
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_axis_tx #(
|
|
||||||
.DATA_WIDTH(64)
|
|
||||||
)
|
|
||||||
eth_axis_tx_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// Ethernet frame input
|
|
||||||
.s_eth_hdr_valid(tx_eth_hdr_valid),
|
|
||||||
.s_eth_hdr_ready(tx_eth_hdr_ready),
|
|
||||||
.s_eth_dest_mac(tx_eth_dest_mac),
|
|
||||||
.s_eth_src_mac(tx_eth_src_mac),
|
|
||||||
.s_eth_type(tx_eth_type),
|
|
||||||
.s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
|
||||||
.s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
|
|
||||||
.s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
|
||||||
.s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
|
||||||
.s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
|
||||||
.s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
|
||||||
// AXI output
|
|
||||||
.m_axis_tdata(tx_axis_tdata),
|
|
||||||
.m_axis_tkeep(tx_axis_tkeep),
|
|
||||||
.m_axis_tvalid(tx_axis_tvalid),
|
|
||||||
.m_axis_tready(tx_axis_tready),
|
|
||||||
.m_axis_tlast(tx_axis_tlast),
|
|
||||||
.m_axis_tuser(tx_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.busy()
|
|
||||||
);
|
|
||||||
|
|
||||||
udp_complete_64
|
|
||||||
udp_complete_inst (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
// Ethernet frame input
|
|
||||||
.s_eth_hdr_valid(rx_eth_hdr_valid),
|
|
||||||
.s_eth_hdr_ready(rx_eth_hdr_ready),
|
|
||||||
.s_eth_dest_mac(rx_eth_dest_mac),
|
|
||||||
.s_eth_src_mac(rx_eth_src_mac),
|
|
||||||
.s_eth_type(rx_eth_type),
|
|
||||||
.s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
|
||||||
.s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
|
|
||||||
.s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
|
||||||
.s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
|
||||||
.s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
|
||||||
.s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
|
||||||
// Ethernet frame output
|
|
||||||
.m_eth_hdr_valid(tx_eth_hdr_valid),
|
|
||||||
.m_eth_hdr_ready(tx_eth_hdr_ready),
|
|
||||||
.m_eth_dest_mac(tx_eth_dest_mac),
|
|
||||||
.m_eth_src_mac(tx_eth_src_mac),
|
|
||||||
.m_eth_type(tx_eth_type),
|
|
||||||
.m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
|
||||||
.m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
|
|
||||||
.m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
|
||||||
.m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
|
||||||
.m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
|
||||||
.m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
|
||||||
// IP frame input
|
|
||||||
.s_ip_hdr_valid(tx_ip_hdr_valid),
|
|
||||||
.s_ip_hdr_ready(tx_ip_hdr_ready),
|
|
||||||
.s_ip_dscp(tx_ip_dscp),
|
|
||||||
.s_ip_ecn(tx_ip_ecn),
|
|
||||||
.s_ip_length(tx_ip_length),
|
|
||||||
.s_ip_ttl(tx_ip_ttl),
|
|
||||||
.s_ip_protocol(tx_ip_protocol),
|
|
||||||
.s_ip_source_ip(tx_ip_source_ip),
|
|
||||||
.s_ip_dest_ip(tx_ip_dest_ip),
|
|
||||||
.s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
|
|
||||||
.s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep),
|
|
||||||
.s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
|
|
||||||
.s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
|
|
||||||
.s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
|
|
||||||
.s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
|
|
||||||
// IP frame output
|
|
||||||
.m_ip_hdr_valid(rx_ip_hdr_valid),
|
|
||||||
.m_ip_hdr_ready(rx_ip_hdr_ready),
|
|
||||||
.m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
|
|
||||||
.m_ip_eth_src_mac(rx_ip_eth_src_mac),
|
|
||||||
.m_ip_eth_type(rx_ip_eth_type),
|
|
||||||
.m_ip_version(rx_ip_version),
|
|
||||||
.m_ip_ihl(rx_ip_ihl),
|
|
||||||
.m_ip_dscp(rx_ip_dscp),
|
|
||||||
.m_ip_ecn(rx_ip_ecn),
|
|
||||||
.m_ip_length(rx_ip_length),
|
|
||||||
.m_ip_identification(rx_ip_identification),
|
|
||||||
.m_ip_flags(rx_ip_flags),
|
|
||||||
.m_ip_fragment_offset(rx_ip_fragment_offset),
|
|
||||||
.m_ip_ttl(rx_ip_ttl),
|
|
||||||
.m_ip_protocol(rx_ip_protocol),
|
|
||||||
.m_ip_header_checksum(rx_ip_header_checksum),
|
|
||||||
.m_ip_source_ip(rx_ip_source_ip),
|
|
||||||
.m_ip_dest_ip(rx_ip_dest_ip),
|
|
||||||
.m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
|
|
||||||
.m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep),
|
|
||||||
.m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
|
|
||||||
.m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
|
|
||||||
.m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
|
|
||||||
.m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
|
|
||||||
// UDP frame input
|
|
||||||
.s_udp_hdr_valid(tx_udp_hdr_valid),
|
|
||||||
.s_udp_hdr_ready(tx_udp_hdr_ready),
|
|
||||||
.s_udp_ip_dscp(tx_udp_ip_dscp),
|
|
||||||
.s_udp_ip_ecn(tx_udp_ip_ecn),
|
|
||||||
.s_udp_ip_ttl(tx_udp_ip_ttl),
|
|
||||||
.s_udp_ip_source_ip(tx_udp_ip_source_ip),
|
|
||||||
.s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
|
|
||||||
.s_udp_source_port(tx_udp_source_port),
|
|
||||||
.s_udp_dest_port(tx_udp_dest_port),
|
|
||||||
.s_udp_length(tx_udp_length),
|
|
||||||
.s_udp_checksum(tx_udp_checksum),
|
|
||||||
.s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
|
|
||||||
.s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep),
|
|
||||||
.s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
|
|
||||||
.s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
|
|
||||||
.s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
|
|
||||||
.s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
|
|
||||||
// UDP frame output
|
|
||||||
.m_udp_hdr_valid(rx_udp_hdr_valid),
|
|
||||||
.m_udp_hdr_ready(rx_udp_hdr_ready),
|
|
||||||
.m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
|
|
||||||
.m_udp_eth_src_mac(rx_udp_eth_src_mac),
|
|
||||||
.m_udp_eth_type(rx_udp_eth_type),
|
|
||||||
.m_udp_ip_version(rx_udp_ip_version),
|
|
||||||
.m_udp_ip_ihl(rx_udp_ip_ihl),
|
|
||||||
.m_udp_ip_dscp(rx_udp_ip_dscp),
|
|
||||||
.m_udp_ip_ecn(rx_udp_ip_ecn),
|
|
||||||
.m_udp_ip_length(rx_udp_ip_length),
|
|
||||||
.m_udp_ip_identification(rx_udp_ip_identification),
|
|
||||||
.m_udp_ip_flags(rx_udp_ip_flags),
|
|
||||||
.m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
|
|
||||||
.m_udp_ip_ttl(rx_udp_ip_ttl),
|
|
||||||
.m_udp_ip_protocol(rx_udp_ip_protocol),
|
|
||||||
.m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
|
|
||||||
.m_udp_ip_source_ip(rx_udp_ip_source_ip),
|
|
||||||
.m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
|
|
||||||
.m_udp_source_port(rx_udp_source_port),
|
|
||||||
.m_udp_dest_port(rx_udp_dest_port),
|
|
||||||
.m_udp_length(rx_udp_length),
|
|
||||||
.m_udp_checksum(rx_udp_checksum),
|
|
||||||
.m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
|
|
||||||
.m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep),
|
|
||||||
.m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
|
|
||||||
.m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
|
|
||||||
.m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
|
|
||||||
.m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
|
|
||||||
// Status signals
|
|
||||||
.ip_rx_busy(),
|
|
||||||
.ip_tx_busy(),
|
|
||||||
.udp_rx_busy(),
|
|
||||||
.udp_tx_busy(),
|
|
||||||
.ip_rx_error_header_early_termination(),
|
|
||||||
.ip_rx_error_payload_early_termination(),
|
|
||||||
.ip_rx_error_invalid_header(),
|
|
||||||
.ip_rx_error_invalid_checksum(),
|
|
||||||
.ip_tx_error_payload_early_termination(),
|
|
||||||
.ip_tx_error_arp_failed(),
|
|
||||||
.udp_rx_error_header_early_termination(),
|
|
||||||
.udp_rx_error_payload_early_termination(),
|
|
||||||
.udp_tx_error_payload_early_termination(),
|
|
||||||
// Configuration
|
|
||||||
.local_mac(local_mac),
|
|
||||||
.local_ip(local_ip),
|
|
||||||
.gateway_ip(gateway_ip),
|
|
||||||
.subnet_mask(subnet_mask),
|
|
||||||
.clear_arp_cache(1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_fifo #(
|
|
||||||
.DEPTH(8192),
|
|
||||||
.DATA_WIDTH(64),
|
|
||||||
.KEEP_ENABLE(1),
|
|
||||||
.KEEP_WIDTH(8),
|
|
||||||
.ID_ENABLE(0),
|
|
||||||
.DEST_ENABLE(0),
|
|
||||||
.USER_ENABLE(1),
|
|
||||||
.USER_WIDTH(1),
|
|
||||||
.FRAME_FIFO(0)
|
|
||||||
)
|
|
||||||
udp_payload_fifo (
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
|
|
||||||
// AXI input
|
|
||||||
.s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
|
|
||||||
.s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep),
|
|
||||||
.s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
|
|
||||||
.s_axis_tready(rx_fifo_udp_payload_axis_tready),
|
|
||||||
.s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
|
|
||||||
.s_axis_tid(0),
|
|
||||||
.s_axis_tdest(0),
|
|
||||||
.s_axis_tuser(rx_fifo_udp_payload_axis_tuser),
|
|
||||||
|
|
||||||
// AXI output
|
|
||||||
.m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
|
|
||||||
.m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep),
|
|
||||||
.m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
|
|
||||||
.m_axis_tready(tx_fifo_udp_payload_axis_tready),
|
|
||||||
.m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
|
|
||||||
.m_axis_tid(),
|
|
||||||
.m_axis_tdest(),
|
|
||||||
.m_axis_tuser(tx_fifo_udp_payload_axis_tuser),
|
|
||||||
|
|
||||||
// Status
|
|
||||||
.status_overflow(),
|
|
||||||
.status_bad_frame(),
|
|
||||||
.status_good_frame()
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
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
|
|
@ -1,95 +0,0 @@
|
|||||||
# Copyright (c) 2020 Alex Forencich
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
|
|
||||||
TOPLEVEL_LANG = verilog
|
|
||||||
|
|
||||||
SIM ?= icarus
|
|
||||||
WAVES ?= 0
|
|
||||||
|
|
||||||
COCOTB_HDL_TIMEUNIT = 1ns
|
|
||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
|
||||||
|
|
||||||
DUT = fpga_core
|
|
||||||
TOPLEVEL = $(DUT)
|
|
||||||
MODULE = test_$(DUT)
|
|
||||||
VERILOG_SOURCES += ../../rtl/$(DUT).v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_rx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|
||||||
|
|
||||||
# module parameters
|
|
||||||
#export PARAM_A := value
|
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
|
||||||
PLUSARGS += -fst
|
|
||||||
|
|
||||||
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
|
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
|
||||||
VERILOG_SOURCES += iverilog_dump.v
|
|
||||||
COMPILE_ARGS += -s iverilog_dump
|
|
||||||
endif
|
|
||||||
else ifeq ($(SIM), verilator)
|
|
||||||
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
|
||||||
|
|
||||||
# COMPILE_ARGS += -GA=$(PARAM_A)
|
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
|
||||||
COMPILE_ARGS += --trace-fst
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
|
||||||
|
|
||||||
iverilog_dump.v:
|
|
||||||
echo 'module iverilog_dump();' > $@
|
|
||||||
echo 'initial begin' >> $@
|
|
||||||
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
|
|
||||||
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
|
|
||||||
echo 'end' >> $@
|
|
||||||
echo 'endmodule' >> $@
|
|
||||||
|
|
||||||
clean::
|
|
||||||
@rm -rf iverilog_dump.v
|
|
||||||
@rm -rf dump.fst $(TOPLEVEL).fst
|
|
@ -1,227 +0,0 @@
|
|||||||
"""
|
|
||||||
|
|
||||||
Copyright (c) 2020 Alex Forencich
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
|
|
||||||
from scapy.layers.l2 import Ether, ARP
|
|
||||||
from scapy.layers.inet import IP, UDP
|
|
||||||
|
|
||||||
import cocotb_test.simulator
|
|
||||||
|
|
||||||
import cocotb
|
|
||||||
from cocotb.log import SimLog
|
|
||||||
from cocotb.clock import Clock
|
|
||||||
from cocotb.triggers import RisingEdge
|
|
||||||
|
|
||||||
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
|
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
|
||||||
def __init__(self, dut):
|
|
||||||
self.dut = dut
|
|
||||||
|
|
||||||
self.log = SimLog("cocotb.tb")
|
|
||||||
self.log.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start())
|
|
||||||
|
|
||||||
# Ethernet
|
|
||||||
self.qsfp_source = []
|
|
||||||
self.qsfp_sink = []
|
|
||||||
|
|
||||||
for x in range(2):
|
|
||||||
sources = []
|
|
||||||
sinks = []
|
|
||||||
for y in range(1, 5):
|
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_rx_clk_{y}"), 2.56, units="ns").start())
|
|
||||||
source = XgmiiSource(getattr(dut, f"qsfp{x}_rxd_{y}"), getattr(dut, f"qsfp{x}_rxc_{y}"), getattr(dut, f"qsfp{x}_rx_clk_{y}"), getattr(dut, f"qsfp{x}_rx_rst_{y}"))
|
|
||||||
sources.append(source)
|
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_tx_clk_{y}"), 2.56, units="ns").start())
|
|
||||||
sink = XgmiiSink(getattr(dut, f"qsfp{x}_txd_{y}"), getattr(dut, f"qsfp{x}_txc_{y}"), getattr(dut, f"qsfp{x}_tx_clk_{y}"), getattr(dut, f"qsfp{x}_tx_rst_{y}"))
|
|
||||||
sinks.append(sink)
|
|
||||||
self.qsfp_source.append(sources)
|
|
||||||
self.qsfp_sink.append(sinks)
|
|
||||||
|
|
||||||
async def init(self):
|
|
||||||
|
|
||||||
self.dut.rst.setimmediatevalue(0)
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").setimmediatevalue(0)
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").setimmediatevalue(0)
|
|
||||||
|
|
||||||
for k in range(10):
|
|
||||||
await RisingEdge(self.dut.clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 1
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 1
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 1
|
|
||||||
|
|
||||||
for k in range(10):
|
|
||||||
await RisingEdge(self.dut.clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 0
|
|
||||||
for x in range(2):
|
|
||||||
for y in range(1, 5):
|
|
||||||
getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 0
|
|
||||||
getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 0
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def run_test(dut):
|
|
||||||
|
|
||||||
tb = TB(dut)
|
|
||||||
|
|
||||||
await tb.init()
|
|
||||||
|
|
||||||
tb.log.info("test UDP RX packet")
|
|
||||||
|
|
||||||
payload = bytes([x % 256 for x in range(256)])
|
|
||||||
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
|
|
||||||
ip = IP(src='192.168.1.100', dst='192.168.1.128')
|
|
||||||
udp = UDP(sport=5678, dport=1234)
|
|
||||||
test_pkt = eth / ip / udp / payload
|
|
||||||
|
|
||||||
test_frame = XgmiiFrame.from_payload(test_pkt.build())
|
|
||||||
|
|
||||||
await tb.qsfp_source[0][0].send(test_frame)
|
|
||||||
|
|
||||||
tb.log.info("receive ARP request")
|
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0][0].recv()
|
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
|
||||||
|
|
||||||
tb.log.info("RX packet: %s", repr(rx_pkt))
|
|
||||||
|
|
||||||
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
|
|
||||||
assert rx_pkt.src == test_pkt.dst
|
|
||||||
assert rx_pkt[ARP].hwtype == 1
|
|
||||||
assert rx_pkt[ARP].ptype == 0x0800
|
|
||||||
assert rx_pkt[ARP].hwlen == 6
|
|
||||||
assert rx_pkt[ARP].plen == 4
|
|
||||||
assert rx_pkt[ARP].op == 1
|
|
||||||
assert rx_pkt[ARP].hwsrc == test_pkt.dst
|
|
||||||
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
|
|
||||||
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
|
|
||||||
assert rx_pkt[ARP].pdst == test_pkt[IP].src
|
|
||||||
|
|
||||||
tb.log.info("send ARP response")
|
|
||||||
|
|
||||||
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
|
|
||||||
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
|
|
||||||
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
|
|
||||||
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
|
|
||||||
resp_pkt = eth / arp
|
|
||||||
|
|
||||||
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
|
|
||||||
|
|
||||||
await tb.qsfp_source[0][0].send(resp_frame)
|
|
||||||
|
|
||||||
tb.log.info("receive UDP packet")
|
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0][0].recv()
|
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
|
||||||
|
|
||||||
tb.log.info("RX packet: %s", repr(rx_pkt))
|
|
||||||
|
|
||||||
assert rx_pkt.dst == test_pkt.src
|
|
||||||
assert rx_pkt.src == test_pkt.dst
|
|
||||||
assert rx_pkt[IP].dst == test_pkt[IP].src
|
|
||||||
assert rx_pkt[IP].src == test_pkt[IP].dst
|
|
||||||
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
|
|
||||||
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
|
|
||||||
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
|
|
||||||
|
|
||||||
await RisingEdge(dut.clk)
|
|
||||||
await RisingEdge(dut.clk)
|
|
||||||
|
|
||||||
|
|
||||||
# cocotb-test
|
|
||||||
|
|
||||||
tests_dir = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
|
||||||
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
|
|
||||||
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
|
|
||||||
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl'))
|
|
||||||
|
|
||||||
|
|
||||||
def test_fpga_core(request):
|
|
||||||
dut = "fpga_core"
|
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
|
||||||
toplevel = dut
|
|
||||||
|
|
||||||
verilog_sources = [
|
|
||||||
os.path.join(rtl_dir, f"{dut}.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "lfsr.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_axis_rx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_cache.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
|
|
||||||
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "arbiter.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "priority_encoder.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_fifo.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
|
|
||||||
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
|
|
||||||
]
|
|
||||||
|
|
||||||
parameters = {}
|
|
||||||
|
|
||||||
# parameters['A'] = val
|
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
|
||||||
|
|
||||||
sim_build = os.path.join(tests_dir, "sim_build",
|
|
||||||
request.node.name.replace('[', '-').replace(']', ''))
|
|
||||||
|
|
||||||
cocotb_test.simulator.run(
|
|
||||||
python_search=[tests_dir],
|
|
||||||
verilog_sources=verilog_sources,
|
|
||||||
toplevel=toplevel,
|
|
||||||
module=module,
|
|
||||||
parameters=parameters,
|
|
||||||
sim_build=sim_build,
|
|
||||||
extra_env=extra_env,
|
|
||||||
)
|
|
@ -1,25 +0,0 @@
|
|||||||
# Targets
|
|
||||||
TARGETS:=
|
|
||||||
|
|
||||||
# Subdirectories
|
|
||||||
SUBDIRS = fpga
|
|
||||||
SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS))
|
|
||||||
|
|
||||||
# Rules
|
|
||||||
.PHONY: all
|
|
||||||
all: $(SUBDIRS) $(TARGETS)
|
|
||||||
|
|
||||||
.PHONY: $(SUBDIRS)
|
|
||||||
$(SUBDIRS):
|
|
||||||
cd $@ && $(MAKE)
|
|
||||||
|
|
||||||
.PHONY: $(SUBDIRS_CLEAN)
|
|
||||||
$(SUBDIRS_CLEAN):
|
|
||||||
cd $(@:.clean=) && $(MAKE) clean
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean: $(SUBDIRS_CLEAN)
|
|
||||||
-rm -rf $(TARGETS)
|
|
||||||
|
|
||||||
program:
|
|
||||||
#djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit
|
|
@ -1,30 +0,0 @@
|
|||||||
# Verilog Ethernet Alveo U50 Example Design
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
This example design targets the Xilinx Alveo U50 FPGA board.
|
|
||||||
|
|
||||||
The design by default listens to UDP port 1234 at IP address 192.168.1.128 and
|
|
||||||
will echo back any packets received. The design will also respond correctly
|
|
||||||
to ARP requests.
|
|
||||||
|
|
||||||
* FPGA: xcu50-fsvh2104-2-e
|
|
||||||
* PHY: 10G BASE-R PHY IP core and internal GTY transceiver
|
|
||||||
|
|
||||||
## How to build
|
|
||||||
|
|
||||||
Run make to build. Ensure that the Xilinx Vivado toolchain components are
|
|
||||||
in PATH.
|
|
||||||
|
|
||||||
## How to test
|
|
||||||
|
|
||||||
Run make program to program the Alveo U50 board with Vivado. Then run
|
|
||||||
|
|
||||||
netcat -u 192.168.1.128 1234
|
|
||||||
|
|
||||||
to open a UDP connection to port 1234. Any text entered into netcat will be
|
|
||||||
echoed back after pressing enter.
|
|
||||||
|
|
||||||
It is also possible to use hping to test the design by running
|
|
||||||
|
|
||||||
hping 192.168.1.128 -2 -p 1234 -d 1024
|
|
@ -1,137 +0,0 @@
|
|||||||
###################################################################
|
|
||||||
#
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
FPGA_TOP ?= fpga
|
|
||||||
PROJECT ?= $(FPGA_TOP)
|
|
||||||
|
|
||||||
SYN_FILES_REL = $(foreach p,$(SYN_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
INC_FILES_REL = $(foreach p,$(INC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
XCI_FILES_REL = $(foreach p,$(XCI_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
IP_TCL_FILES_REL = $(foreach p,$(IP_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
CONFIG_TCL_FILES_REL = $(foreach p,$(CONFIG_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
|
|
||||||
ifdef XDC_FILES
|
|
||||||
XDC_FILES_REL = $(foreach p,$(XDC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
|
|
||||||
else
|
|
||||||
XDC_FILES_REL = $(PROJECT).xdc
|
|
||||||
endif
|
|
||||||
|
|
||||||
###################################################################
|
|
||||||
# Main Targets
|
|
||||||
#
|
|
||||||
# all: build everything
|
|
||||||
# clean: remove output files and project files
|
|
||||||
###################################################################
|
|
||||||
|
|
||||||
all: fpga
|
|
||||||
|
|
||||||
fpga: $(PROJECT).bit
|
|
||||||
|
|
||||||
vivado: $(PROJECT).xpr
|
|
||||||
vivado $(PROJECT).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 *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
|
|
||||||
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
|
|
||||||
|
|
||||||
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) $(PROJECT)" > $@
|
|
||||||
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
|
|
||||||
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
|
|
||||||
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) $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
|
|
||||||
echo "open_project -quiet $(PROJECT).xpr" > $@
|
|
||||||
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
|
|
||||||
|
|
||||||
$(PROJECT).xpr: create_project.tcl update_config.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
|
|
||||||
|
|
||||||
# synthesis run
|
|
||||||
$(PROJECT).runs/synth_1/$(PROJECT).dcp: create_project.tcl update_config.tcl $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) | $(PROJECT).xpr
|
|
||||||
echo "open_project $(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
|
|
||||||
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
|
|
||||||
echo "open_project $(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
|
|
||||||
echo "open_run impl_1" >> run_impl.tcl
|
|
||||||
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
|
|
||||||
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source run_impl.tcl
|
|
||||||
|
|
||||||
# bit file
|
|
||||||
$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
|
|
||||||
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
|
|
||||||
echo "open_run impl_1" >> generate_bit.tcl
|
|
||||||
echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
|
|
||||||
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
|
|
||||||
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
|
|
||||||
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
|
|
||||||
mkdir -p rev
|
|
||||||
COUNT=100; \
|
|
||||||
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
|
|
||||||
do COUNT=$$((COUNT+1)); done; \
|
|
||||||
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
|
|
||||||
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi
|
|
@ -1,76 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
set base_name {eth_xcvr_gt}
|
|
||||||
|
|
||||||
set preset {GTY-10GBASE-R}
|
|
||||||
|
|
||||||
set freerun_freq {125}
|
|
||||||
set line_rate {10.3125}
|
|
||||||
set refclk_freq {161.1328125}
|
|
||||||
set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}]
|
|
||||||
set user_data_width {64}
|
|
||||||
set int_data_width $user_data_width
|
|
||||||
set extra_ports [list]
|
|
||||||
set extra_pll_ports [list {qpll0lock_out}]
|
|
||||||
|
|
||||||
set config [dict create]
|
|
||||||
|
|
||||||
dict set config TX_LINE_RATE $line_rate
|
|
||||||
dict set config TX_REFCLK_FREQUENCY $refclk_freq
|
|
||||||
dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn
|
|
||||||
dict set config TX_USER_DATA_WIDTH $user_data_width
|
|
||||||
dict set config TX_INT_DATA_WIDTH $int_data_width
|
|
||||||
dict set config RX_LINE_RATE $line_rate
|
|
||||||
dict set config RX_REFCLK_FREQUENCY $refclk_freq
|
|
||||||
dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn
|
|
||||||
dict set config RX_USER_DATA_WIDTH $user_data_width
|
|
||||||
dict set config RX_INT_DATA_WIDTH $int_data_width
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
|
|
||||||
dict set config LOCATE_COMMON {CORE}
|
|
||||||
dict set config LOCATE_RESET_CONTROLLER {CORE}
|
|
||||||
dict set config LOCATE_TX_USER_CLOCKING {CORE}
|
|
||||||
dict set config LOCATE_RX_USER_CLOCKING {CORE}
|
|
||||||
dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE}
|
|
||||||
dict set config FREERUN_FREQUENCY $freerun_freq
|
|
||||||
dict set config DISABLE_LOC_XDC {1}
|
|
||||||
|
|
||||||
proc create_gtwizard_ip {name preset config} {
|
|
||||||
create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name
|
|
||||||
set ip [get_ips $name]
|
|
||||||
set_property CONFIG.preset $preset $ip
|
|
||||||
set config_list {}
|
|
||||||
dict for {name value} $config {
|
|
||||||
lappend config_list "CONFIG.${name}" $value
|
|
||||||
}
|
|
||||||
set_property -dict $config_list $ip
|
|
||||||
}
|
|
||||||
|
|
||||||
# variant with channel and common
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports]
|
|
||||||
dict set config LOCATE_COMMON {CORE}
|
|
||||||
|
|
||||||
create_gtwizard_ip "${base_name}_full" $preset $config
|
|
||||||
|
|
||||||
# variant with channel only
|
|
||||||
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
|
|
||||||
dict set config LOCATE_COMMON {EXAMPLE_DESIGN}
|
|
||||||
|
|
||||||
create_gtwizard_ip "${base_name}_channel" $preset $config
|
|
@ -1 +0,0 @@
|
|||||||
../../../../
|
|
@ -1,395 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2023 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transceiver and PHY quad wrapper
|
|
||||||
*/
|
|
||||||
module eth_xcvr_phy_quad_wrapper #
|
|
||||||
(
|
|
||||||
parameter COUNT = 4,
|
|
||||||
parameter DATA_WIDTH = 64,
|
|
||||||
parameter CTRL_WIDTH = (DATA_WIDTH/8),
|
|
||||||
parameter HDR_WIDTH = 2,
|
|
||||||
parameter PRBS31_ENABLE = 0,
|
|
||||||
parameter TX_SERDES_PIPELINE = 0,
|
|
||||||
parameter RX_SERDES_PIPELINE = 0,
|
|
||||||
parameter BITSLIP_HIGH_CYCLES = 1,
|
|
||||||
parameter BITSLIP_LOW_CYCLES = 8,
|
|
||||||
parameter COUNT_125US = 125000/6.4
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input wire xcvr_ctrl_clk,
|
|
||||||
input wire xcvr_ctrl_rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common
|
|
||||||
*/
|
|
||||||
output wire xcvr_gtpowergood_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL
|
|
||||||
*/
|
|
||||||
input wire xcvr_gtrefclk00_in,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Serial data
|
|
||||||
*/
|
|
||||||
output wire [COUNT-1:0] xcvr_txp,
|
|
||||||
output wire [COUNT-1:0] xcvr_txn,
|
|
||||||
input wire [COUNT-1:0] xcvr_rxp,
|
|
||||||
input wire [COUNT-1:0] xcvr_rxn,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PHY connections
|
|
||||||
*/
|
|
||||||
output wire phy_1_tx_clk,
|
|
||||||
output wire phy_1_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_1_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_1_xgmii_txc,
|
|
||||||
output wire phy_1_rx_clk,
|
|
||||||
output wire phy_1_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_1_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_1_xgmii_rxc,
|
|
||||||
output wire phy_1_tx_bad_block,
|
|
||||||
output wire [6:0] phy_1_rx_error_count,
|
|
||||||
output wire phy_1_rx_bad_block,
|
|
||||||
output wire phy_1_rx_sequence_error,
|
|
||||||
output wire phy_1_rx_block_lock,
|
|
||||||
output wire phy_1_rx_high_ber,
|
|
||||||
output wire phy_1_rx_status,
|
|
||||||
input wire phy_1_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_1_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_2_tx_clk,
|
|
||||||
output wire phy_2_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_2_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_2_xgmii_txc,
|
|
||||||
output wire phy_2_rx_clk,
|
|
||||||
output wire phy_2_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_2_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_2_xgmii_rxc,
|
|
||||||
output wire phy_2_tx_bad_block,
|
|
||||||
output wire [6:0] phy_2_rx_error_count,
|
|
||||||
output wire phy_2_rx_bad_block,
|
|
||||||
output wire phy_2_rx_sequence_error,
|
|
||||||
output wire phy_2_rx_block_lock,
|
|
||||||
output wire phy_2_rx_high_ber,
|
|
||||||
output wire phy_2_rx_status,
|
|
||||||
input wire phy_2_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_2_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_3_tx_clk,
|
|
||||||
output wire phy_3_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_3_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_3_xgmii_txc,
|
|
||||||
output wire phy_3_rx_clk,
|
|
||||||
output wire phy_3_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_3_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_3_xgmii_rxc,
|
|
||||||
output wire phy_3_tx_bad_block,
|
|
||||||
output wire [6:0] phy_3_rx_error_count,
|
|
||||||
output wire phy_3_rx_bad_block,
|
|
||||||
output wire phy_3_rx_sequence_error,
|
|
||||||
output wire phy_3_rx_block_lock,
|
|
||||||
output wire phy_3_rx_high_ber,
|
|
||||||
output wire phy_3_rx_status,
|
|
||||||
input wire phy_3_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_3_cfg_rx_prbs31_enable,
|
|
||||||
|
|
||||||
output wire phy_4_tx_clk,
|
|
||||||
output wire phy_4_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_4_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_4_xgmii_txc,
|
|
||||||
output wire phy_4_rx_clk,
|
|
||||||
output wire phy_4_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_4_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_4_xgmii_rxc,
|
|
||||||
output wire phy_4_tx_bad_block,
|
|
||||||
output wire [6:0] phy_4_rx_error_count,
|
|
||||||
output wire phy_4_rx_bad_block,
|
|
||||||
output wire phy_4_rx_sequence_error,
|
|
||||||
output wire phy_4_rx_block_lock,
|
|
||||||
output wire phy_4_rx_high_ber,
|
|
||||||
output wire phy_4_rx_status,
|
|
||||||
input wire phy_4_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_4_cfg_rx_prbs31_enable
|
|
||||||
);
|
|
||||||
|
|
||||||
generate
|
|
||||||
|
|
||||||
wire xcvr_qpll0lock;
|
|
||||||
wire xcvr_qpll0clk;
|
|
||||||
wire xcvr_qpll0refclk;
|
|
||||||
|
|
||||||
if (COUNT > 0) begin : phy1
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(1),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_1 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(xcvr_gtrefclk00_in),
|
|
||||||
.xcvr_qpll0lock_out(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_out(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_out(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(1'b0),
|
|
||||||
.xcvr_qpll0clk_in(1'b0),
|
|
||||||
.xcvr_qpll0refclk_in(1'b0),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[0]),
|
|
||||||
.xcvr_txn(xcvr_txn[0]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[0]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[0]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_1_tx_clk),
|
|
||||||
.phy_tx_rst(phy_1_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_1_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_1_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_1_rx_clk),
|
|
||||||
.phy_rx_rst(phy_1_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_1_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_1_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_1_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_1_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_1_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_1_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_1_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_1_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_1_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_1_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_1_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 1) begin : phy2
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_2 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[1]),
|
|
||||||
.xcvr_txn(xcvr_txn[1]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[1]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[1]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_2_tx_clk),
|
|
||||||
.phy_tx_rst(phy_2_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_2_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_2_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_2_rx_clk),
|
|
||||||
.phy_rx_rst(phy_2_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_2_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_2_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_2_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_2_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_2_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_2_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_2_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_2_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_2_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_2_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_2_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 2) begin : phy3
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_3 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[2]),
|
|
||||||
.xcvr_txn(xcvr_txn[2]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[2]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[2]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_3_tx_clk),
|
|
||||||
.phy_tx_rst(phy_3_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_3_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_3_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_3_rx_clk),
|
|
||||||
.phy_rx_rst(phy_3_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_3_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_3_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_3_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_3_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_3_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_3_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_3_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_3_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_3_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_3_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_3_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if (COUNT > 3) begin : phy4
|
|
||||||
|
|
||||||
eth_xcvr_phy_wrapper #(
|
|
||||||
.HAS_COMMON(0),
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
eth_xcvr_phy_4 (
|
|
||||||
.xcvr_ctrl_clk(xcvr_ctrl_clk),
|
|
||||||
.xcvr_ctrl_rst(xcvr_ctrl_rst),
|
|
||||||
|
|
||||||
// Common
|
|
||||||
.xcvr_gtpowergood_out(),
|
|
||||||
|
|
||||||
// PLL out
|
|
||||||
.xcvr_gtrefclk00_in(1'b0),
|
|
||||||
.xcvr_qpll0lock_out(),
|
|
||||||
.xcvr_qpll0clk_out(),
|
|
||||||
.xcvr_qpll0refclk_out(),
|
|
||||||
|
|
||||||
// PLL in
|
|
||||||
.xcvr_qpll0lock_in(xcvr_qpll0lock),
|
|
||||||
.xcvr_qpll0clk_in(xcvr_qpll0clk),
|
|
||||||
.xcvr_qpll0refclk_in(xcvr_qpll0refclk),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.xcvr_txp(xcvr_txp[3]),
|
|
||||||
.xcvr_txn(xcvr_txn[3]),
|
|
||||||
.xcvr_rxp(xcvr_rxp[3]),
|
|
||||||
.xcvr_rxn(xcvr_rxn[3]),
|
|
||||||
|
|
||||||
// PHY connections
|
|
||||||
.phy_tx_clk(phy_4_tx_clk),
|
|
||||||
.phy_tx_rst(phy_4_tx_rst),
|
|
||||||
.phy_xgmii_txd(phy_4_xgmii_txd),
|
|
||||||
.phy_xgmii_txc(phy_4_xgmii_txc),
|
|
||||||
.phy_rx_clk(phy_4_rx_clk),
|
|
||||||
.phy_rx_rst(phy_4_rx_rst),
|
|
||||||
.phy_xgmii_rxd(phy_4_xgmii_rxd),
|
|
||||||
.phy_xgmii_rxc(phy_4_xgmii_rxc),
|
|
||||||
.phy_tx_bad_block(phy_4_tx_bad_block),
|
|
||||||
.phy_rx_error_count(phy_4_rx_error_count),
|
|
||||||
.phy_rx_bad_block(phy_4_rx_bad_block),
|
|
||||||
.phy_rx_sequence_error(phy_4_rx_sequence_error),
|
|
||||||
.phy_rx_block_lock(phy_4_rx_block_lock),
|
|
||||||
.phy_rx_high_ber(phy_4_rx_high_ber),
|
|
||||||
.phy_rx_status(phy_4_rx_status),
|
|
||||||
.phy_cfg_tx_prbs31_enable(phy_4_cfg_tx_prbs31_enable),
|
|
||||||
.phy_cfg_rx_prbs31_enable(phy_4_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,307 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2021-2023 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transceiver and PHY wrapper
|
|
||||||
*/
|
|
||||||
module eth_xcvr_phy_wrapper #
|
|
||||||
(
|
|
||||||
parameter HAS_COMMON = 1,
|
|
||||||
parameter DATA_WIDTH = 64,
|
|
||||||
parameter CTRL_WIDTH = (DATA_WIDTH/8),
|
|
||||||
parameter HDR_WIDTH = 2,
|
|
||||||
parameter PRBS31_ENABLE = 0,
|
|
||||||
parameter TX_SERDES_PIPELINE = 0,
|
|
||||||
parameter RX_SERDES_PIPELINE = 0,
|
|
||||||
parameter BITSLIP_HIGH_CYCLES = 1,
|
|
||||||
parameter BITSLIP_LOW_CYCLES = 8,
|
|
||||||
parameter COUNT_125US = 125000/6.4
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input wire xcvr_ctrl_clk,
|
|
||||||
input wire xcvr_ctrl_rst,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Common
|
|
||||||
*/
|
|
||||||
output wire xcvr_gtpowergood_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL out
|
|
||||||
*/
|
|
||||||
input wire xcvr_gtrefclk00_in,
|
|
||||||
output wire xcvr_qpll0lock_out,
|
|
||||||
output wire xcvr_qpll0clk_out,
|
|
||||||
output wire xcvr_qpll0refclk_out,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PLL in
|
|
||||||
*/
|
|
||||||
input wire xcvr_qpll0lock_in,
|
|
||||||
output wire xcvr_qpll0reset_out,
|
|
||||||
input wire xcvr_qpll0clk_in,
|
|
||||||
input wire xcvr_qpll0refclk_in,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Serial data
|
|
||||||
*/
|
|
||||||
output wire xcvr_txp,
|
|
||||||
output wire xcvr_txn,
|
|
||||||
input wire xcvr_rxp,
|
|
||||||
input wire xcvr_rxn,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PHY connections
|
|
||||||
*/
|
|
||||||
output wire phy_tx_clk,
|
|
||||||
output wire phy_tx_rst,
|
|
||||||
input wire [DATA_WIDTH-1:0] phy_xgmii_txd,
|
|
||||||
input wire [CTRL_WIDTH-1:0] phy_xgmii_txc,
|
|
||||||
output wire phy_rx_clk,
|
|
||||||
output wire phy_rx_rst,
|
|
||||||
output wire [DATA_WIDTH-1:0] phy_xgmii_rxd,
|
|
||||||
output wire [CTRL_WIDTH-1:0] phy_xgmii_rxc,
|
|
||||||
output wire phy_tx_bad_block,
|
|
||||||
output wire [6:0] phy_rx_error_count,
|
|
||||||
output wire phy_rx_bad_block,
|
|
||||||
output wire phy_rx_sequence_error,
|
|
||||||
output wire phy_rx_block_lock,
|
|
||||||
output wire phy_rx_high_ber,
|
|
||||||
output wire phy_rx_status,
|
|
||||||
input wire phy_cfg_tx_prbs31_enable,
|
|
||||||
input wire phy_cfg_rx_prbs31_enable
|
|
||||||
);
|
|
||||||
|
|
||||||
wire phy_rx_reset_req;
|
|
||||||
|
|
||||||
wire gt_reset_tx_datapath = 1'b0;
|
|
||||||
wire gt_reset_rx_datapath = phy_rx_reset_req;
|
|
||||||
|
|
||||||
wire gt_reset_tx_done;
|
|
||||||
wire gt_reset_rx_done;
|
|
||||||
|
|
||||||
wire [5:0] gt_txheader;
|
|
||||||
wire [63:0] gt_txdata;
|
|
||||||
wire gt_rxgearboxslip;
|
|
||||||
wire [5:0] gt_rxheader;
|
|
||||||
wire [1:0] gt_rxheadervalid;
|
|
||||||
wire [63:0] gt_rxdata;
|
|
||||||
wire [1:0] gt_rxdatavalid;
|
|
||||||
|
|
||||||
generate
|
|
||||||
|
|
||||||
if (HAS_COMMON) begin : xcvr
|
|
||||||
|
|
||||||
eth_xcvr_gt_full
|
|
||||||
eth_xcvr_gt_full_inst (
|
|
||||||
// Common
|
|
||||||
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
|
|
||||||
.gtwiz_reset_all_in(xcvr_ctrl_rst),
|
|
||||||
.gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL
|
|
||||||
.gtrefclk00_in(xcvr_gtrefclk00_in),
|
|
||||||
.qpll0lock_out(xcvr_qpll0lock_out),
|
|
||||||
.qpll0outclk_out(xcvr_qpll0clk_out),
|
|
||||||
.qpll0outrefclk_out(xcvr_qpll0refclk_out),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.gtytxp_out(xcvr_txp),
|
|
||||||
.gtytxn_out(xcvr_txn),
|
|
||||||
.gtyrxp_in(xcvr_rxp),
|
|
||||||
.gtyrxn_in(xcvr_rxn),
|
|
||||||
|
|
||||||
// Transmit
|
|
||||||
.gtwiz_userclk_tx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_tx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
|
|
||||||
.gtwiz_userclk_tx_active_out(),
|
|
||||||
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
|
|
||||||
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
|
|
||||||
.txpmaresetdone_out(),
|
|
||||||
.txprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.gtwiz_userdata_tx_in(gt_txdata),
|
|
||||||
.txheader_in(gt_txheader),
|
|
||||||
.txsequence_in(7'b0),
|
|
||||||
|
|
||||||
// Receive
|
|
||||||
.gtwiz_userclk_rx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_rx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
|
|
||||||
.gtwiz_userclk_rx_active_out(),
|
|
||||||
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
|
|
||||||
.gtwiz_reset_rx_cdr_stable_out(),
|
|
||||||
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
|
|
||||||
.rxpmaresetdone_out(),
|
|
||||||
.rxprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.rxgearboxslip_in(gt_rxgearboxslip),
|
|
||||||
.gtwiz_userdata_rx_out(gt_rxdata),
|
|
||||||
.rxdatavalid_out(gt_rxdatavalid),
|
|
||||||
.rxheader_out(gt_rxheader),
|
|
||||||
.rxheadervalid_out(gt_rxheadervalid),
|
|
||||||
.rxstartofseq_out()
|
|
||||||
);
|
|
||||||
|
|
||||||
assign xcvr_qpll0reset_out = 1'b0;
|
|
||||||
|
|
||||||
end else begin : xcvr
|
|
||||||
|
|
||||||
eth_xcvr_gt_channel
|
|
||||||
eth_xcvr_gt_channel_inst (
|
|
||||||
// Common
|
|
||||||
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
|
|
||||||
.gtwiz_reset_all_in(xcvr_ctrl_rst),
|
|
||||||
.gtpowergood_out(xcvr_gtpowergood_out),
|
|
||||||
|
|
||||||
// PLL
|
|
||||||
.gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in),
|
|
||||||
.gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out),
|
|
||||||
.qpll0clk_in(xcvr_qpll0clk_in),
|
|
||||||
.qpll0refclk_in(xcvr_qpll0refclk_in),
|
|
||||||
.qpll1clk_in(1'b0),
|
|
||||||
.qpll1refclk_in(1'b0),
|
|
||||||
|
|
||||||
// Serial data
|
|
||||||
.gtytxp_out(xcvr_txp),
|
|
||||||
.gtytxn_out(xcvr_txn),
|
|
||||||
.gtyrxp_in(xcvr_rxp),
|
|
||||||
.gtyrxn_in(xcvr_rxn),
|
|
||||||
|
|
||||||
// Transmit
|
|
||||||
.gtwiz_userclk_tx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_tx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
|
|
||||||
.gtwiz_userclk_tx_active_out(),
|
|
||||||
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
|
|
||||||
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
|
|
||||||
.txpmaresetdone_out(),
|
|
||||||
.txprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.gtwiz_userdata_tx_in(gt_txdata),
|
|
||||||
.txheader_in(gt_txheader),
|
|
||||||
.txsequence_in(7'b0),
|
|
||||||
|
|
||||||
// Receive
|
|
||||||
.gtwiz_userclk_rx_reset_in(1'b0),
|
|
||||||
.gtwiz_userclk_rx_srcclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk_out(),
|
|
||||||
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
|
|
||||||
.gtwiz_userclk_rx_active_out(),
|
|
||||||
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
|
|
||||||
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
|
|
||||||
.gtwiz_reset_rx_cdr_stable_out(),
|
|
||||||
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
|
|
||||||
.rxpmaresetdone_out(),
|
|
||||||
.rxprgdivresetdone_out(),
|
|
||||||
|
|
||||||
.rxgearboxslip_in(gt_rxgearboxslip),
|
|
||||||
.gtwiz_userdata_rx_out(gt_rxdata),
|
|
||||||
.rxdatavalid_out(gt_rxdatavalid),
|
|
||||||
.rxheader_out(gt_rxheader),
|
|
||||||
.rxheadervalid_out(gt_rxheadervalid),
|
|
||||||
.rxstartofseq_out()
|
|
||||||
);
|
|
||||||
|
|
||||||
assign xcvr_qpll0lock_out = 1'b0;
|
|
||||||
assign xcvr_qpll0clk_out = 1'b0;
|
|
||||||
assign xcvr_qpll0refclk_out = 1'b0;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
sync_reset #(
|
|
||||||
.N(4)
|
|
||||||
)
|
|
||||||
tx_reset_sync_inst (
|
|
||||||
.clk(phy_tx_clk),
|
|
||||||
.rst(!gt_reset_tx_done),
|
|
||||||
.out(phy_tx_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
sync_reset #(
|
|
||||||
.N(4)
|
|
||||||
)
|
|
||||||
rx_reset_sync_inst (
|
|
||||||
.clk(phy_rx_clk),
|
|
||||||
.rst(!gt_reset_rx_done),
|
|
||||||
.out(phy_rx_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
eth_phy_10g #(
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.CTRL_WIDTH(CTRL_WIDTH),
|
|
||||||
.HDR_WIDTH(HDR_WIDTH),
|
|
||||||
.BIT_REVERSE(1),
|
|
||||||
.SCRAMBLER_DISABLE(0),
|
|
||||||
.PRBS31_ENABLE(PRBS31_ENABLE),
|
|
||||||
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
|
|
||||||
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
|
|
||||||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
|
|
||||||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
|
|
||||||
.COUNT_125US(COUNT_125US)
|
|
||||||
)
|
|
||||||
phy_inst (
|
|
||||||
.tx_clk(phy_tx_clk),
|
|
||||||
.tx_rst(phy_tx_rst),
|
|
||||||
.rx_clk(phy_rx_clk),
|
|
||||||
.rx_rst(phy_rx_rst),
|
|
||||||
.xgmii_txd(phy_xgmii_txd),
|
|
||||||
.xgmii_txc(phy_xgmii_txc),
|
|
||||||
.xgmii_rxd(phy_xgmii_rxd),
|
|
||||||
.xgmii_rxc(phy_xgmii_rxc),
|
|
||||||
.serdes_tx_data(gt_txdata),
|
|
||||||
.serdes_tx_hdr(gt_txheader),
|
|
||||||
.serdes_rx_data(gt_rxdata),
|
|
||||||
.serdes_rx_hdr(gt_rxheader),
|
|
||||||
.serdes_rx_bitslip(gt_rxgearboxslip),
|
|
||||||
.serdes_rx_reset_req(phy_rx_reset_req),
|
|
||||||
.tx_bad_block(phy_tx_bad_block),
|
|
||||||
.rx_error_count(phy_rx_error_count),
|
|
||||||
.rx_bad_block(phy_rx_bad_block),
|
|
||||||
.rx_sequence_error(phy_rx_sequence_error),
|
|
||||||
.rx_block_lock(phy_rx_block_lock),
|
|
||||||
.rx_high_ber(phy_rx_high_ber),
|
|
||||||
.rx_status(phy_rx_status),
|
|
||||||
.cfg_tx_prbs31_enable(phy_cfg_tx_prbs31_enable),
|
|
||||||
.cfg_rx_prbs31_enable(phy_cfg_rx_prbs31_enable)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
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
|
|
@ -1,95 +0,0 @@
|
|||||||
# Copyright (c) 2020 Alex Forencich
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
|
|
||||||
TOPLEVEL_LANG = verilog
|
|
||||||
|
|
||||||
SIM ?= icarus
|
|
||||||
WAVES ?= 0
|
|
||||||
|
|
||||||
COCOTB_HDL_TIMEUNIT = 1ns
|
|
||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
|
||||||
|
|
||||||
DUT = fpga_core
|
|
||||||
TOPLEVEL = $(DUT)
|
|
||||||
MODULE = test_$(DUT)
|
|
||||||
VERILOG_SOURCES += ../../rtl/$(DUT).v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_rx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
|
|
||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|
||||||
|
|
||||||
# module parameters
|
|
||||||
#export PARAM_A := value
|
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
|
||||||
PLUSARGS += -fst
|
|
||||||
|
|
||||||
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
|
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
|
||||||
VERILOG_SOURCES += iverilog_dump.v
|
|
||||||
COMPILE_ARGS += -s iverilog_dump
|
|
||||||
endif
|
|
||||||
else ifeq ($(SIM), verilator)
|
|
||||||
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
|
||||||
|
|
||||||
# COMPILE_ARGS += -GA=$(PARAM_A)
|
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
|
||||||
COMPILE_ARGS += --trace-fst
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
|
||||||
|
|
||||||
iverilog_dump.v:
|
|
||||||
echo 'module iverilog_dump();' > $@
|
|
||||||
echo 'initial begin' >> $@
|
|
||||||
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
|
|
||||||
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
|
|
||||||
echo 'end' >> $@
|
|
||||||
echo 'endmodule' >> $@
|
|
||||||
|
|
||||||
clean::
|
|
||||||
@rm -rf iverilog_dump.v
|
|
||||||
@rm -rf dump.fst $(TOPLEVEL).fst
|
|
@ -1,14 +1,18 @@
|
|||||||
# Verilog Ethernet Alveo U200/Alveo U250/VCU1525 Example Design
|
# Verilog Ethernet Alveo Example Design
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
This example design targets the Xilinx Alveo U200/Alveo U250/VCU1525 FPGA board.
|
This design targets multiple FPGA boards, including most of the Xilinx Alveo line.
|
||||||
|
|
||||||
The design by default listens to UDP port 1234 at IP address 192.168.1.128 and will echo back any packets received. The design will also respond correctly to ARP requests.
|
The design by default listens to UDP port 1234 at IP address 192.168.1.128 and will echo back any packets received. The design will also respond correctly to ARP requests.
|
||||||
|
|
||||||
* FPGA
|
* FPGA
|
||||||
|
* AU50: xcu50-fsvh2104-2-e
|
||||||
|
* AU55C: xcu55c-fsvh2892-2L-e
|
||||||
|
* AU55N/C1100: xcu55n-fsvh2892-2L-e
|
||||||
* AU200: xcu200-fsgd2104-2-e
|
* AU200: xcu200-fsgd2104-2-e
|
||||||
* AU250: xcu250-fsgd2104-2-e
|
* AU250: xcu250-fsgd2104-2-e
|
||||||
|
* AU280: xcu280-fsvh2892-2L-e
|
||||||
* VCU1525: xcvu9p-fsgd2104-2L-e
|
* VCU1525: xcvu9p-fsgd2104-2L-e
|
||||||
* PHY: 10G BASE-R PHY IP core and internal GTY transceiver
|
* PHY: 10G BASE-R PHY IP core and internal GTY transceiver
|
||||||
|
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au280.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -51,7 +51,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au280.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au280.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -51,7 +51,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au280.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au50.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -51,7 +51,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au50.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au50.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -51,7 +51,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au50.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55C/Makefile
Normal file
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55C/Makefile
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
# FPGA settings
|
||||||
|
FPGA_PART = xcu55c-fsvh2892-2L-e
|
||||||
|
FPGA_TOP = fpga
|
||||||
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
|
# Files for synthesis
|
||||||
|
SYN_FILES = rtl/fpga_au55.v
|
||||||
|
SYN_FILES += rtl/fpga_core.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
|
SYN_FILES += rtl/sync_signal.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/lfsr.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_cache.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
|
# XDC files
|
||||||
|
XDC_FILES = fpga_au55.xdc
|
||||||
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
||||||
|
|
||||||
|
# IP
|
||||||
|
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONFIG_TCL_FILES = ./config.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 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||||
|
echo "exit" >> generate_mcs.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||||
|
mkdir -p rev
|
||||||
|
COUNT=100; \
|
||||||
|
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||||
|
do COUNT=$$((COUNT+1)); done; \
|
||||||
|
COUNT=$$((COUNT-1)); \
|
||||||
|
for x in .mcs .prm; \
|
||||||
|
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||||
|
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||||
|
|
||||||
|
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||||
|
echo "open_hw" > flash.tcl
|
||||||
|
echo "connect_hw_server" >> flash.tcl
|
||||||
|
echo "open_hw_target" >> flash.tcl
|
||||||
|
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||||
|
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
|
||||||
|
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "exit" >> flash.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||||
|
|
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55C_10g/Makefile
Normal file
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55C_10g/Makefile
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
# FPGA settings
|
||||||
|
FPGA_PART = xcu55c-fsvh2892-2L-e
|
||||||
|
FPGA_TOP = fpga
|
||||||
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
|
# Files for synthesis
|
||||||
|
SYN_FILES = rtl/fpga_au55.v
|
||||||
|
SYN_FILES += rtl/fpga_core.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
|
SYN_FILES += rtl/sync_signal.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/lfsr.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_cache.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
|
# XDC files
|
||||||
|
XDC_FILES = fpga_au55.xdc
|
||||||
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
||||||
|
|
||||||
|
# IP
|
||||||
|
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONFIG_TCL_FILES = ./config.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 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||||
|
echo "exit" >> generate_mcs.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||||
|
mkdir -p rev
|
||||||
|
COUNT=100; \
|
||||||
|
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||||
|
do COUNT=$$((COUNT+1)); done; \
|
||||||
|
COUNT=$$((COUNT-1)); \
|
||||||
|
for x in .mcs .prm; \
|
||||||
|
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||||
|
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||||
|
|
||||||
|
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||||
|
echo "open_hw" > flash.tcl
|
||||||
|
echo "connect_hw_server" >> flash.tcl
|
||||||
|
echo "open_hw_target" >> flash.tcl
|
||||||
|
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||||
|
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
|
||||||
|
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "exit" >> flash.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||||
|
|
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N/Makefile
Normal file
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N/Makefile
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
# FPGA settings
|
||||||
|
FPGA_PART = xcu55n-fsvh2892-2L-e
|
||||||
|
FPGA_TOP = fpga
|
||||||
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
|
# Files for synthesis
|
||||||
|
SYN_FILES = rtl/fpga_au55.v
|
||||||
|
SYN_FILES += rtl/fpga_core.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
|
SYN_FILES += rtl/sync_signal.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/lfsr.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_cache.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
|
# XDC files
|
||||||
|
XDC_FILES = fpga_au55.xdc
|
||||||
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
||||||
|
|
||||||
|
# IP
|
||||||
|
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONFIG_TCL_FILES = ./config.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 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||||
|
echo "exit" >> generate_mcs.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||||
|
mkdir -p rev
|
||||||
|
COUNT=100; \
|
||||||
|
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||||
|
do COUNT=$$((COUNT+1)); done; \
|
||||||
|
COUNT=$$((COUNT-1)); \
|
||||||
|
for x in .mcs .prm; \
|
||||||
|
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||||
|
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||||
|
|
||||||
|
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||||
|
echo "open_hw" > flash.tcl
|
||||||
|
echo "connect_hw_server" >> flash.tcl
|
||||||
|
echo "open_hw_target" >> flash.tcl
|
||||||
|
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||||
|
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
|
||||||
|
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "exit" >> flash.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||||
|
|
50
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N/config.tcl
Normal file
50
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N/config.tcl
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Copyright (c) 2023 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.
|
||||||
|
|
||||||
|
# Transceiver configuration
|
||||||
|
set eth_xcvr_freerun_freq {125}
|
||||||
|
set eth_xcvr_line_rate {25.78125}
|
||||||
|
set eth_xcvr_sec_line_rate {0}
|
||||||
|
set eth_xcvr_refclk_freq {161.1328125}
|
||||||
|
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_rx_eq_mode {DFE}
|
||||||
|
|
||||||
|
set xcvr_config [dict create]
|
||||||
|
|
||||||
|
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
|
||||||
|
if {$eth_xcvr_sec_line_rate != 0} {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
} else {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
|
||||||
|
}
|
||||||
|
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
|
||||||
|
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]
|
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N_10g/Makefile
Normal file
114
fpga/lib/eth/example/Alveo/fpga_25g/fpga_AU55N_10g/Makefile
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
# FPGA settings
|
||||||
|
FPGA_PART = xcu55n-fsvh2892-2L-e
|
||||||
|
FPGA_TOP = fpga
|
||||||
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
|
# Files for synthesis
|
||||||
|
SYN_FILES = rtl/fpga_au55.v
|
||||||
|
SYN_FILES += rtl/fpga_core.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
|
SYN_FILES += rtl/sync_signal.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/lfsr.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_axis_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_complete_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v
|
||||||
|
SYN_FILES += lib/eth/rtl/ip_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_cache.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
|
||||||
|
SYN_FILES += lib/eth/rtl/eth_arb_mux.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
|
# XDC files
|
||||||
|
XDC_FILES = fpga_au55.xdc
|
||||||
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
||||||
|
|
||||||
|
# IP
|
||||||
|
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONFIG_TCL_FILES = ./config.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 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||||
|
echo "exit" >> generate_mcs.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||||
|
mkdir -p rev
|
||||||
|
COUNT=100; \
|
||||||
|
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||||
|
do COUNT=$$((COUNT+1)); done; \
|
||||||
|
COUNT=$$((COUNT-1)); \
|
||||||
|
for x in .mcs .prm; \
|
||||||
|
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||||
|
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||||
|
|
||||||
|
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||||
|
echo "open_hw" > flash.tcl
|
||||||
|
echo "connect_hw_server" >> flash.tcl
|
||||||
|
echo "open_hw_target" >> flash.tcl
|
||||||
|
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||||
|
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
|
||||||
|
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||||
|
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||||
|
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||||
|
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||||
|
echo "exit" >> flash.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
# Copyright (c) 2023 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.
|
||||||
|
|
||||||
|
# Transceiver configuration
|
||||||
|
set eth_xcvr_freerun_freq {125}
|
||||||
|
set eth_xcvr_line_rate {10.3125}
|
||||||
|
set eth_xcvr_sec_line_rate {0}
|
||||||
|
set eth_xcvr_refclk_freq {161.1328125}
|
||||||
|
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_rx_eq_mode {DFE}
|
||||||
|
|
||||||
|
set xcvr_config [dict create]
|
||||||
|
|
||||||
|
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
|
||||||
|
if {$eth_xcvr_sec_line_rate != 0} {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
} else {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
|
||||||
|
}
|
||||||
|
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
|
||||||
|
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
50
fpga/lib/eth/example/Alveo/fpga_25g/fpga_VCU1525/config.tcl
Normal file
50
fpga/lib/eth/example/Alveo/fpga_25g/fpga_VCU1525/config.tcl
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Copyright (c) 2023 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.
|
||||||
|
|
||||||
|
# Transceiver configuration
|
||||||
|
set eth_xcvr_freerun_freq {125}
|
||||||
|
set eth_xcvr_line_rate {25.78125}
|
||||||
|
set eth_xcvr_sec_line_rate {0}
|
||||||
|
set eth_xcvr_refclk_freq {161.1328125}
|
||||||
|
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_rx_eq_mode {DFE}
|
||||||
|
|
||||||
|
set xcvr_config [dict create]
|
||||||
|
|
||||||
|
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
|
||||||
|
if {$eth_xcvr_sec_line_rate != 0} {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
} else {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
|
||||||
|
}
|
||||||
|
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
|
||||||
|
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]
|
@ -5,7 +5,7 @@ FPGA_TOP = fpga
|
|||||||
FPGA_ARCH = virtexuplus
|
FPGA_ARCH = virtexuplus
|
||||||
|
|
||||||
# Files for synthesis
|
# Files for synthesis
|
||||||
SYN_FILES = rtl/fpga.v
|
SYN_FILES = rtl/fpga_au200.v
|
||||||
SYN_FILES += rtl/fpga_core.v
|
SYN_FILES += rtl/fpga_core.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_wrapper.v
|
||||||
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
SYN_FILES += rtl/eth_xcvr_phy_quad_wrapper.v
|
||||||
@ -52,7 +52,7 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
|||||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||||
|
|
||||||
# XDC files
|
# XDC files
|
||||||
XDC_FILES = fpga.xdc
|
XDC_FILES = fpga_au200.xdc
|
||||||
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
XDC_FILES += lib/eth/syn/vivado/eth_mac_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl
|
||||||
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
|
@ -0,0 +1,50 @@
|
|||||||
|
# Copyright (c) 2023 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.
|
||||||
|
|
||||||
|
# Transceiver configuration
|
||||||
|
set eth_xcvr_freerun_freq {125}
|
||||||
|
set eth_xcvr_line_rate {10.3125}
|
||||||
|
set eth_xcvr_sec_line_rate {0}
|
||||||
|
set eth_xcvr_refclk_freq {161.1328125}
|
||||||
|
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
|
||||||
|
set eth_xcvr_rx_eq_mode {DFE}
|
||||||
|
|
||||||
|
set xcvr_config [dict create]
|
||||||
|
|
||||||
|
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
|
||||||
|
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
|
||||||
|
if {$eth_xcvr_sec_line_rate != 0} {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
|
||||||
|
} else {
|
||||||
|
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
|
||||||
|
}
|
||||||
|
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
|
||||||
|
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
|
||||||
|
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]
|
@ -45,8 +45,8 @@ set_false_path -from [get_ports {reset}]
|
|||||||
set_input_delay 0 [get_ports {reset}]
|
set_input_delay 0 [get_ports {reset}]
|
||||||
|
|
||||||
# UART
|
# UART
|
||||||
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart_txd]
|
set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd]
|
||||||
#set_property -dict {LOC B33 IOSTANDARD LVCMOS18} [get_ports usb_uart_rxd]
|
set_property -dict {LOC B33 IOSTANDARD LVCMOS18} [get_ports uart_rxd]
|
||||||
|
|
||||||
#set_false_path -to [get_ports {uart_txd}]
|
#set_false_path -to [get_ports {uart_txd}]
|
||||||
#set_output_delay 0 [get_ports {uart_txd}]
|
#set_output_delay 0 [get_ports {uart_txd}]
|
@ -37,17 +37,17 @@ set_false_path -to [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
|
|||||||
set_output_delay 0 [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
|
set_output_delay 0 [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
|
||||||
|
|
||||||
# UART
|
# UART
|
||||||
#set_property -dict {LOC BE26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart0_txd]
|
set_property -dict {LOC BE26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[0]}]
|
||||||
#set_property -dict {LOC BF26 IOSTANDARD LVCMOS18} [get_ports usb_uart0_rxd]
|
set_property -dict {LOC BF26 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[0]}]
|
||||||
#set_property -dict {LOC A17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart1_txd]
|
set_property -dict {LOC A17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[1]}]
|
||||||
#set_property -dict {LOC B15 IOSTANDARD LVCMOS18} [get_ports usb_uart1_rxd]
|
set_property -dict {LOC B15 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[1]}]
|
||||||
#set_property -dict {LOC A19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart2_txd]
|
set_property -dict {LOC A19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[2]}]
|
||||||
#set_property -dict {LOC A18 IOSTANDARD LVCMOS18} [get_ports usb_uart2_rxd]
|
set_property -dict {LOC A18 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[2]}]
|
||||||
|
|
||||||
#set_false_path -to [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
|
#set_false_path -to [get_ports {uart_txd[*]}]
|
||||||
#set_output_delay 0 [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
|
#set_output_delay 0 [get_ports {uart_txd[*]}]
|
||||||
#set_false_path -from [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
|
#set_false_path -from [get_ports {uart_rxd[*]}]
|
||||||
#set_input_delay 0 [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
|
#set_input_delay 0 [get_ports {uart_rxd[*]}]
|
||||||
|
|
||||||
# BMC
|
# BMC
|
||||||
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
|
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
|
236
fpga/lib/eth/example/Alveo/fpga_25g/fpga_au55.xdc
Normal file
236
fpga/lib/eth/example/Alveo/fpga_25g/fpga_au55.xdc
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
# XDC constraints for the Xilinx Alveo U55C/Alveo U55N/Varium C1100 board
|
||||||
|
# U55C part: xcu55c-fsvh2892-2L-e
|
||||||
|
# U55N/C1100 part: xcu55n-fsvh2892-2L-e
|
||||||
|
|
||||||
|
# General configuration
|
||||||
|
set_property CFGBVS GND [current_design]
|
||||||
|
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
|
||||||
|
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||||
|
set_property CONFIG_MODE SPIx4 [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
|
||||||
|
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
|
||||||
|
|
||||||
|
#set_operating_conditions -design_power_budget 63
|
||||||
|
|
||||||
|
# System clocks
|
||||||
|
# 100 MHz
|
||||||
|
#set_property -dict {LOC BK10 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
|
||||||
|
#set_property -dict {LOC BL10 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
|
||||||
|
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
|
||||||
|
|
||||||
|
# 100 MHz
|
||||||
|
#set_property -dict {LOC BK43 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
|
||||||
|
#set_property -dict {LOC BK44 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
|
||||||
|
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
|
||||||
|
|
||||||
|
# 100 MHz
|
||||||
|
#set_property -dict {LOC F24 IOSTANDARD LVDS} [get_ports clk_100mhz_2_p]
|
||||||
|
#set_property -dict {LOC F23 IOSTANDARD LVDS} [get_ports clk_100mhz_2_n]
|
||||||
|
#create_clock -period 10 -name clk_100mhz_2 [get_ports clk_100mhz_2_p]
|
||||||
|
|
||||||
|
# Reset button
|
||||||
|
set_property -dict {LOC BG45 IOSTANDARD LVCMOS18} [get_ports reset]
|
||||||
|
|
||||||
|
set_false_path -from [get_ports {reset}]
|
||||||
|
set_input_delay 0 [get_ports {reset}]
|
||||||
|
|
||||||
|
# LEDs
|
||||||
|
set_property -dict {LOC BL13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[0]}]
|
||||||
|
set_property -dict {LOC BK11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[0]}]
|
||||||
|
set_property -dict {LOC BJ11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[0]}]
|
||||||
|
set_property -dict {LOC BK14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[1]}]
|
||||||
|
set_property -dict {LOC BK15 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[1]}]
|
||||||
|
set_property -dict {LOC BL12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[1]}]
|
||||||
|
|
||||||
|
set_false_path -to [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
|
||||||
|
set_output_delay 0 [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
|
||||||
|
|
||||||
|
# UART
|
||||||
|
set_property -dict {LOC BJ41 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[0]}]
|
||||||
|
set_property -dict {LOC BK41 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[0]}]
|
||||||
|
set_property -dict {LOC BN47 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[1]}]
|
||||||
|
set_property -dict {LOC BP47 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[1]}]
|
||||||
|
set_property -dict {LOC BL45 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[2]}]
|
||||||
|
set_property -dict {LOC BL46 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[2]}]
|
||||||
|
|
||||||
|
#set_false_path -to [get_ports {uart_txd[*]}]
|
||||||
|
#set_output_delay 0 [get_ports {uart_txd[*]}]
|
||||||
|
#set_false_path -from [get_ports {uart_rxd[*]}]
|
||||||
|
#set_input_delay 0 [get_ports {uart_rxd[*]}]
|
||||||
|
|
||||||
|
# BMC
|
||||||
|
#set_property -dict {LOC BE46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
|
||||||
|
#set_property -dict {LOC BH46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
|
||||||
|
#set_property -dict {LOC BF45 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
|
||||||
|
#set_property -dict {LOC BF46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
|
||||||
|
#set_property -dict {LOC BH42 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
|
||||||
|
#set_property -dict {LOC BJ42 IOSTANDARD LVCMOS18} [get_ports {msp_uart_rxd}]
|
||||||
|
|
||||||
|
#set_false_path -to [get_ports {msp_uart_txd}]
|
||||||
|
#set_output_delay 0 [get_ports {msp_uart_txd}]
|
||||||
|
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
|
||||||
|
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
|
||||||
|
|
||||||
|
# HBM overtemp
|
||||||
|
set_property -dict {LOC BE45 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
|
||||||
|
|
||||||
|
set_false_path -to [get_ports {hbm_cattrip}]
|
||||||
|
set_output_delay 0 [get_ports {hbm_cattrip}]
|
||||||
|
|
||||||
|
# SI5394 (SI5394B-A10605-GM)
|
||||||
|
# I2C address 0x68
|
||||||
|
# IN0: 161.1328125 MHz from qsfp_recclk
|
||||||
|
# OUT0: 161.1328125 MHz to qsfp0_mgt_refclk
|
||||||
|
# OUT1: 161.1328125 MHz to qsfp1_mgt_refclk
|
||||||
|
# OUT3: 100 MHz to clk_100mhz_0, clk_100mhz_1, pcie_refclk_2, pcie_refclk_3
|
||||||
|
#set_property -dict {LOC BM8 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports si5394_rst_b]
|
||||||
|
#set_property -dict {LOC BM9 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_int_b]
|
||||||
|
#set_property -dict {LOC BN10 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_lol_b]
|
||||||
|
#set_property -dict {LOC BM10 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_los_b]
|
||||||
|
#set_property -dict {LOC BN14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_sda]
|
||||||
|
#set_property -dict {LOC BM14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_scl]
|
||||||
|
|
||||||
|
#set_false_path -to [get_ports {si5394_rst_b}]
|
||||||
|
#set_output_delay 0 [get_ports {si5394_rst_b}]
|
||||||
|
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
|
||||||
|
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
|
||||||
|
|
||||||
|
#set_false_path -to [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||||
|
#set_output_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||||
|
#set_false_path -from [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||||
|
#set_input_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||||
|
|
||||||
|
# QSFP28 Interfaces
|
||||||
|
set_property -dict {LOC AD51} [get_ports {qsfp0_rx_p[0]}] ;# MGTYRXP0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AD52} [get_ports {qsfp0_rx_n[0]}] ;# MGTYRXN0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AD46} [get_ports {qsfp0_tx_p[0]}] ;# MGTYTXP0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AD47} [get_ports {qsfp0_tx_n[0]}] ;# MGTYTXN0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC53} [get_ports {qsfp0_rx_p[1]}] ;# MGTYRXP1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC54} [get_ports {qsfp0_rx_n[1]}] ;# MGTYRXN1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC44} [get_ports {qsfp0_tx_p[1]}] ;# MGTYTXP1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC45} [get_ports {qsfp0_tx_n[1]}] ;# MGTYTXN1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC49} [get_ports {qsfp0_rx_p[2]}] ;# MGTYRXP2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AC50} [get_ports {qsfp0_rx_n[2]}] ;# MGTYRXN2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AB46} [get_ports {qsfp0_tx_p[2]}] ;# MGTYTXP2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AB47} [get_ports {qsfp0_tx_n[2]}] ;# MGTYTXN2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AB51} [get_ports {qsfp0_rx_p[3]}] ;# MGTYRXP3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AB52} [get_ports {qsfp0_rx_n[3]}] ;# MGTYRXN3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AA48} [get_ports {qsfp0_tx_p[3]}] ;# MGTYTXP3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AA49} [get_ports {qsfp0_tx_n[3]}] ;# MGTYTXN3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AD42} [get_ports qsfp0_mgt_refclk_p] ;# MGTREFCLK0P_130 from SI5394 OUT0
|
||||||
|
set_property -dict {LOC AD43} [get_ports qsfp0_mgt_refclk_n] ;# MGTREFCLK0N_130 from SI5394 OUT0
|
||||||
|
|
||||||
|
# 161.1328125 MHz MGT reference clock (SI5394 OUT0)
|
||||||
|
create_clock -period 6.206 -name qsfp0_mgt_refclk [get_ports qsfp0_mgt_refclk_p]
|
||||||
|
|
||||||
|
set_property -dict {LOC AA53} [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AA54} [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AA44} [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AA45} [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC Y51 } [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC Y52 } [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC Y46 } [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC Y47 } [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W53 } [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W54 } [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W48 } [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W49 } [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC V51 } [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC V52 } [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W44 } [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC W45 } [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||||
|
set_property -dict {LOC AB42} [get_ports qsfp1_mgt_refclk_p] ;# MGTREFCLK0P_131 from SI5394 OUT1
|
||||||
|
set_property -dict {LOC AB43} [get_ports qsfp1_mgt_refclk_n] ;# MGTREFCLK0N_131 from SI5394 OUT1
|
||||||
|
|
||||||
|
# 161.1328125 MHz MGT reference clock (SI5394 OUT1)
|
||||||
|
create_clock -period 6.206 -name qsfp1_mgt_refclk [get_ports qsfp1_mgt_refclk_p]
|
||||||
|
|
||||||
|
# PCIe Interface
|
||||||
|
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AL11} [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AL10} [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AM9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN6 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN5 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN11} [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN10} [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AP9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AP8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||||
|
#set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR11} [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR10} [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AR6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AT9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AT8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AU11} [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AU10} [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||||
|
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AV9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AV8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW11} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AW10} [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AY9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC AY8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||||
|
#set_property -dict {LOC BA6 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BA5 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BA11} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BA10} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BB9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BB8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC11} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC10} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC BC6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||||
|
#set_property -dict {LOC AL15} [get_ports pcie_refclk_0_p] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
|
||||||
|
#set_property -dict {LOC AL14} [get_ports pcie_refclk_0_n] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
|
||||||
|
#set_property -dict {LOC AK13} [get_ports pcie_refclk_2_p] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
|
||||||
|
#set_property -dict {LOC AK12} [get_ports pcie_refclk_2_n] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
|
||||||
|
#set_property -dict {LOC AR15} [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
|
||||||
|
#set_property -dict {LOC AR14} [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
|
||||||
|
#set_property -dict {LOC AP13} [get_ports pcie_refclk_3_p] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
|
||||||
|
#set_property -dict {LOC AP12} [get_ports pcie_refclk_3_n] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
|
||||||
|
#set_property -dict {LOC BF41 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
|
||||||
|
|
||||||
|
# 100 MHz MGT reference clock
|
||||||
|
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports pcie_refclk_0_p]
|
||||||
|
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
|
||||||
|
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
|
||||||
|
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports pcie_refclk_3_p]
|
||||||
|
|
||||||
|
#set_false_path -from [get_ports {pcie_reset_n}]
|
||||||
|
#set_input_delay 0 [get_ports {pcie_reset_n}]
|
@ -49,6 +49,12 @@ module fpga (
|
|||||||
inout wire i2c_scl,
|
inout wire i2c_scl,
|
||||||
inout wire i2c_sda,
|
inout wire i2c_sda,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
output wire uart_txd,
|
||||||
|
input wire uart_rxd,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
@ -82,13 +88,7 @@ module fpga (
|
|||||||
input wire qsfp1_intl,
|
input wire qsfp1_intl,
|
||||||
output wire qsfp1_lpmode,
|
output wire qsfp1_lpmode,
|
||||||
output wire qsfp1_refclk_reset,
|
output wire qsfp1_refclk_reset,
|
||||||
output wire [1:0] qsfp1_fs,
|
output wire [1:0] qsfp1_fs
|
||||||
|
|
||||||
/*
|
|
||||||
* UART: 500000 bps, 8N1
|
|
||||||
*/
|
|
||||||
output wire uart_rxd,
|
|
||||||
input wire uart_txd
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clock and reset
|
// Clock and reset
|
||||||
@ -198,18 +198,6 @@ debounce_switch_inst (
|
|||||||
.out({sw_int})
|
.out({sw_int})
|
||||||
);
|
);
|
||||||
|
|
||||||
wire uart_txd_int;
|
|
||||||
|
|
||||||
sync_signal #(
|
|
||||||
.WIDTH(1),
|
|
||||||
.N(2)
|
|
||||||
)
|
|
||||||
sync_signal_inst (
|
|
||||||
.clk(clk_156mhz_int),
|
|
||||||
.in({uart_txd}),
|
|
||||||
.out({uart_txd_int})
|
|
||||||
);
|
|
||||||
|
|
||||||
// SI570 I2C
|
// SI570 I2C
|
||||||
wire i2c_scl_i;
|
wire i2c_scl_i;
|
||||||
wire i2c_scl_o = 1'b1;
|
wire i2c_scl_o = 1'b1;
|
||||||
@ -282,6 +270,20 @@ always @(posedge cfgmclk_int) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// XGMII 10G PHY
|
// XGMII 10G PHY
|
||||||
|
localparam QSFP_CNT = 2;
|
||||||
|
localparam CH_CNT = QSFP_CNT*4;
|
||||||
|
|
||||||
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_txc;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_rxd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_rxc;
|
||||||
|
|
||||||
|
assign clk_156mhz_int = eth_tx_clk[0];
|
||||||
|
assign rst_156mhz_int = eth_tx_rst[0];
|
||||||
|
|
||||||
// QSFP0
|
// QSFP0
|
||||||
assign qsfp0_modsell = 1'b0;
|
assign qsfp0_modsell = 1'b0;
|
||||||
@ -290,42 +292,6 @@ assign qsfp0_lpmode = 1'b0;
|
|||||||
assign qsfp0_refclk_reset = qsfp_refclk_reset_reg;
|
assign qsfp0_refclk_reset = qsfp_refclk_reset_reg;
|
||||||
assign qsfp0_fs = 2'b10;
|
assign qsfp0_fs = 2'b10;
|
||||||
|
|
||||||
wire qsfp0_tx_clk_1_int;
|
|
||||||
wire qsfp0_tx_rst_1_int;
|
|
||||||
wire [63:0] qsfp0_txd_1_int;
|
|
||||||
wire [7:0] qsfp0_txc_1_int;
|
|
||||||
wire qsfp0_rx_clk_1_int;
|
|
||||||
wire qsfp0_rx_rst_1_int;
|
|
||||||
wire [63:0] qsfp0_rxd_1_int;
|
|
||||||
wire [7:0] qsfp0_rxc_1_int;
|
|
||||||
wire qsfp0_tx_clk_2_int;
|
|
||||||
wire qsfp0_tx_rst_2_int;
|
|
||||||
wire [63:0] qsfp0_txd_2_int;
|
|
||||||
wire [7:0] qsfp0_txc_2_int;
|
|
||||||
wire qsfp0_rx_clk_2_int;
|
|
||||||
wire qsfp0_rx_rst_2_int;
|
|
||||||
wire [63:0] qsfp0_rxd_2_int;
|
|
||||||
wire [7:0] qsfp0_rxc_2_int;
|
|
||||||
wire qsfp0_tx_clk_3_int;
|
|
||||||
wire qsfp0_tx_rst_3_int;
|
|
||||||
wire [63:0] qsfp0_txd_3_int;
|
|
||||||
wire [7:0] qsfp0_txc_3_int;
|
|
||||||
wire qsfp0_rx_clk_3_int;
|
|
||||||
wire qsfp0_rx_rst_3_int;
|
|
||||||
wire [63:0] qsfp0_rxd_3_int;
|
|
||||||
wire [7:0] qsfp0_rxc_3_int;
|
|
||||||
wire qsfp0_tx_clk_4_int;
|
|
||||||
wire qsfp0_tx_rst_4_int;
|
|
||||||
wire [63:0] qsfp0_txd_4_int;
|
|
||||||
wire [7:0] qsfp0_txc_4_int;
|
|
||||||
wire qsfp0_rx_clk_4_int;
|
|
||||||
wire qsfp0_rx_rst_4_int;
|
|
||||||
wire [63:0] qsfp0_rxd_4_int;
|
|
||||||
wire [7:0] qsfp0_rxc_4_int;
|
|
||||||
|
|
||||||
assign clk_156mhz_int = qsfp0_tx_clk_1_int;
|
|
||||||
assign rst_156mhz_int = qsfp0_tx_rst_1_int;
|
|
||||||
|
|
||||||
wire qsfp0_rx_block_lock_1;
|
wire qsfp0_rx_block_lock_1;
|
||||||
wire qsfp0_rx_block_lock_2;
|
wire qsfp0_rx_block_lock_2;
|
||||||
wire qsfp0_rx_block_lock_3;
|
wire qsfp0_rx_block_lock_3;
|
||||||
@ -387,14 +353,14 @@ qsfp0_phy_inst (
|
|||||||
/*
|
/*
|
||||||
* PHY connections
|
* PHY connections
|
||||||
*/
|
*/
|
||||||
.phy_1_tx_clk(qsfp0_tx_clk_1_int),
|
.phy_1_tx_clk(eth_tx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_tx_rst(qsfp0_tx_rst_1_int),
|
.phy_1_tx_rst(eth_tx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_txd(qsfp0_txd_1_int),
|
.phy_1_xgmii_txd(eth_txd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_txc(qsfp0_txc_1_int),
|
.phy_1_xgmii_txc(eth_txc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_rx_clk(qsfp0_rx_clk_1_int),
|
.phy_1_rx_clk(eth_rx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_rx_rst(qsfp0_rx_rst_1_int),
|
.phy_1_rx_rst(eth_rx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_rxd(qsfp0_rxd_1_int),
|
.phy_1_xgmii_rxd(eth_rxd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_rxc(qsfp0_rxc_1_int),
|
.phy_1_xgmii_rxc(eth_rxc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_tx_bad_block(),
|
.phy_1_tx_bad_block(),
|
||||||
.phy_1_rx_error_count(),
|
.phy_1_rx_error_count(),
|
||||||
.phy_1_rx_bad_block(),
|
.phy_1_rx_bad_block(),
|
||||||
@ -404,14 +370,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_2_tx_clk(qsfp0_tx_clk_2_int),
|
.phy_2_tx_clk(eth_tx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_tx_rst(qsfp0_tx_rst_2_int),
|
.phy_2_tx_rst(eth_tx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_txd(qsfp0_txd_2_int),
|
.phy_2_xgmii_txd(eth_txd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_txc(qsfp0_txc_2_int),
|
.phy_2_xgmii_txc(eth_txc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_rx_clk(qsfp0_rx_clk_2_int),
|
.phy_2_rx_clk(eth_rx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_rx_rst(qsfp0_rx_rst_2_int),
|
.phy_2_rx_rst(eth_rx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_rxd(qsfp0_rxd_2_int),
|
.phy_2_xgmii_rxd(eth_rxd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_rxc(qsfp0_rxc_2_int),
|
.phy_2_xgmii_rxc(eth_rxc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_tx_bad_block(),
|
.phy_2_tx_bad_block(),
|
||||||
.phy_2_rx_error_count(),
|
.phy_2_rx_error_count(),
|
||||||
.phy_2_rx_bad_block(),
|
.phy_2_rx_bad_block(),
|
||||||
@ -421,14 +387,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_3_tx_clk(qsfp0_tx_clk_3_int),
|
.phy_3_tx_clk(eth_tx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_tx_rst(qsfp0_tx_rst_3_int),
|
.phy_3_tx_rst(eth_tx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_txd(qsfp0_txd_3_int),
|
.phy_3_xgmii_txd(eth_txd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_txc(qsfp0_txc_3_int),
|
.phy_3_xgmii_txc(eth_txc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_rx_clk(qsfp0_rx_clk_3_int),
|
.phy_3_rx_clk(eth_rx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_rx_rst(qsfp0_rx_rst_3_int),
|
.phy_3_rx_rst(eth_rx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_rxd(qsfp0_rxd_3_int),
|
.phy_3_xgmii_rxd(eth_rxd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_rxc(qsfp0_rxc_3_int),
|
.phy_3_xgmii_rxc(eth_rxc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_tx_bad_block(),
|
.phy_3_tx_bad_block(),
|
||||||
.phy_3_rx_error_count(),
|
.phy_3_rx_error_count(),
|
||||||
.phy_3_rx_bad_block(),
|
.phy_3_rx_bad_block(),
|
||||||
@ -438,14 +404,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_4_tx_clk(qsfp0_tx_clk_4_int),
|
.phy_4_tx_clk(eth_tx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_tx_rst(qsfp0_tx_rst_4_int),
|
.phy_4_tx_rst(eth_tx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_txd(qsfp0_txd_4_int),
|
.phy_4_xgmii_txd(eth_txd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_txc(qsfp0_txc_4_int),
|
.phy_4_xgmii_txc(eth_txc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_rx_clk(qsfp0_rx_clk_4_int),
|
.phy_4_rx_clk(eth_rx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_rx_rst(qsfp0_rx_rst_4_int),
|
.phy_4_rx_rst(eth_rx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_rxd(qsfp0_rxd_4_int),
|
.phy_4_xgmii_rxd(eth_rxd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_rxc(qsfp0_rxc_4_int),
|
.phy_4_xgmii_rxc(eth_rxc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_tx_bad_block(),
|
.phy_4_tx_bad_block(),
|
||||||
.phy_4_rx_error_count(),
|
.phy_4_rx_error_count(),
|
||||||
.phy_4_rx_bad_block(),
|
.phy_4_rx_bad_block(),
|
||||||
@ -463,39 +429,6 @@ assign qsfp1_lpmode = 1'b0;
|
|||||||
assign qsfp1_refclk_reset = qsfp_refclk_reset_reg;
|
assign qsfp1_refclk_reset = qsfp_refclk_reset_reg;
|
||||||
assign qsfp1_fs = 2'b10;
|
assign qsfp1_fs = 2'b10;
|
||||||
|
|
||||||
wire qsfp1_tx_clk_1_int;
|
|
||||||
wire qsfp1_tx_rst_1_int;
|
|
||||||
wire [63:0] qsfp1_txd_1_int;
|
|
||||||
wire [7:0] qsfp1_txc_1_int;
|
|
||||||
wire qsfp1_rx_clk_1_int;
|
|
||||||
wire qsfp1_rx_rst_1_int;
|
|
||||||
wire [63:0] qsfp1_rxd_1_int;
|
|
||||||
wire [7:0] qsfp1_rxc_1_int;
|
|
||||||
wire qsfp1_tx_clk_2_int;
|
|
||||||
wire qsfp1_tx_rst_2_int;
|
|
||||||
wire [63:0] qsfp1_txd_2_int;
|
|
||||||
wire [7:0] qsfp1_txc_2_int;
|
|
||||||
wire qsfp1_rx_clk_2_int;
|
|
||||||
wire qsfp1_rx_rst_2_int;
|
|
||||||
wire [63:0] qsfp1_rxd_2_int;
|
|
||||||
wire [7:0] qsfp1_rxc_2_int;
|
|
||||||
wire qsfp1_tx_clk_3_int;
|
|
||||||
wire qsfp1_tx_rst_3_int;
|
|
||||||
wire [63:0] qsfp1_txd_3_int;
|
|
||||||
wire [7:0] qsfp1_txc_3_int;
|
|
||||||
wire qsfp1_rx_clk_3_int;
|
|
||||||
wire qsfp1_rx_rst_3_int;
|
|
||||||
wire [63:0] qsfp1_rxd_3_int;
|
|
||||||
wire [7:0] qsfp1_rxc_3_int;
|
|
||||||
wire qsfp1_tx_clk_4_int;
|
|
||||||
wire qsfp1_tx_rst_4_int;
|
|
||||||
wire [63:0] qsfp1_txd_4_int;
|
|
||||||
wire [7:0] qsfp1_txc_4_int;
|
|
||||||
wire qsfp1_rx_clk_4_int;
|
|
||||||
wire qsfp1_rx_rst_4_int;
|
|
||||||
wire [63:0] qsfp1_rxd_4_int;
|
|
||||||
wire [7:0] qsfp1_rxc_4_int;
|
|
||||||
|
|
||||||
wire qsfp1_rx_block_lock_1;
|
wire qsfp1_rx_block_lock_1;
|
||||||
wire qsfp1_rx_block_lock_2;
|
wire qsfp1_rx_block_lock_2;
|
||||||
wire qsfp1_rx_block_lock_3;
|
wire qsfp1_rx_block_lock_3;
|
||||||
@ -541,14 +474,14 @@ qsfp1_phy_inst (
|
|||||||
/*
|
/*
|
||||||
* PHY connections
|
* PHY connections
|
||||||
*/
|
*/
|
||||||
.phy_1_tx_clk(qsfp1_tx_clk_1_int),
|
.phy_1_tx_clk(eth_tx_clk[1*4+0 +: 1]),
|
||||||
.phy_1_tx_rst(qsfp1_tx_rst_1_int),
|
.phy_1_tx_rst(eth_tx_rst[1*4+0 +: 1]),
|
||||||
.phy_1_xgmii_txd(qsfp1_txd_1_int),
|
.phy_1_xgmii_txd(eth_txd[(1*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_txc(qsfp1_txc_1_int),
|
.phy_1_xgmii_txc(eth_txc[(1*4+0)*8 +: 8]),
|
||||||
.phy_1_rx_clk(qsfp1_rx_clk_1_int),
|
.phy_1_rx_clk(eth_rx_clk[1*4+0 +: 1]),
|
||||||
.phy_1_rx_rst(qsfp1_rx_rst_1_int),
|
.phy_1_rx_rst(eth_rx_rst[1*4+0 +: 1]),
|
||||||
.phy_1_xgmii_rxd(qsfp1_rxd_1_int),
|
.phy_1_xgmii_rxd(eth_rxd[(1*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_rxc(qsfp1_rxc_1_int),
|
.phy_1_xgmii_rxc(eth_rxc[(1*4+0)*8 +: 8]),
|
||||||
.phy_1_tx_bad_block(),
|
.phy_1_tx_bad_block(),
|
||||||
.phy_1_rx_error_count(),
|
.phy_1_rx_error_count(),
|
||||||
.phy_1_rx_bad_block(),
|
.phy_1_rx_bad_block(),
|
||||||
@ -558,14 +491,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_2_tx_clk(qsfp1_tx_clk_2_int),
|
.phy_2_tx_clk(eth_tx_clk[1*4+1 +: 1]),
|
||||||
.phy_2_tx_rst(qsfp1_tx_rst_2_int),
|
.phy_2_tx_rst(eth_tx_rst[1*4+1 +: 1]),
|
||||||
.phy_2_xgmii_txd(qsfp1_txd_2_int),
|
.phy_2_xgmii_txd(eth_txd[(1*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_txc(qsfp1_txc_2_int),
|
.phy_2_xgmii_txc(eth_txc[(1*4+1)*8 +: 8]),
|
||||||
.phy_2_rx_clk(qsfp1_rx_clk_2_int),
|
.phy_2_rx_clk(eth_rx_clk[1*4+1 +: 1]),
|
||||||
.phy_2_rx_rst(qsfp1_rx_rst_2_int),
|
.phy_2_rx_rst(eth_rx_rst[1*4+1 +: 1]),
|
||||||
.phy_2_xgmii_rxd(qsfp1_rxd_2_int),
|
.phy_2_xgmii_rxd(eth_rxd[(1*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_rxc(qsfp1_rxc_2_int),
|
.phy_2_xgmii_rxc(eth_rxc[(1*4+1)*8 +: 8]),
|
||||||
.phy_2_tx_bad_block(),
|
.phy_2_tx_bad_block(),
|
||||||
.phy_2_rx_error_count(),
|
.phy_2_rx_error_count(),
|
||||||
.phy_2_rx_bad_block(),
|
.phy_2_rx_bad_block(),
|
||||||
@ -575,14 +508,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_3_tx_clk(qsfp1_tx_clk_3_int),
|
.phy_3_tx_clk(eth_tx_clk[1*4+2 +: 1]),
|
||||||
.phy_3_tx_rst(qsfp1_tx_rst_3_int),
|
.phy_3_tx_rst(eth_tx_rst[1*4+2 +: 1]),
|
||||||
.phy_3_xgmii_txd(qsfp1_txd_3_int),
|
.phy_3_xgmii_txd(eth_txd[(1*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_txc(qsfp1_txc_3_int),
|
.phy_3_xgmii_txc(eth_txc[(1*4+2)*8 +: 8]),
|
||||||
.phy_3_rx_clk(qsfp1_rx_clk_3_int),
|
.phy_3_rx_clk(eth_rx_clk[1*4+2 +: 1]),
|
||||||
.phy_3_rx_rst(qsfp1_rx_rst_3_int),
|
.phy_3_rx_rst(eth_rx_rst[1*4+2 +: 1]),
|
||||||
.phy_3_xgmii_rxd(qsfp1_rxd_3_int),
|
.phy_3_xgmii_rxd(eth_rxd[(1*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_rxc(qsfp1_rxc_3_int),
|
.phy_3_xgmii_rxc(eth_rxc[(1*4+2)*8 +: 8]),
|
||||||
.phy_3_tx_bad_block(),
|
.phy_3_tx_bad_block(),
|
||||||
.phy_3_rx_error_count(),
|
.phy_3_rx_error_count(),
|
||||||
.phy_3_rx_bad_block(),
|
.phy_3_rx_bad_block(),
|
||||||
@ -592,14 +525,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_4_tx_clk(qsfp1_tx_clk_4_int),
|
.phy_4_tx_clk(eth_tx_clk[1*4+3 +: 1]),
|
||||||
.phy_4_tx_rst(qsfp1_tx_rst_4_int),
|
.phy_4_tx_rst(eth_tx_rst[1*4+3 +: 1]),
|
||||||
.phy_4_xgmii_txd(qsfp1_txd_4_int),
|
.phy_4_xgmii_txd(eth_txd[(1*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_txc(qsfp1_txc_4_int),
|
.phy_4_xgmii_txc(eth_txc[(1*4+3)*8 +: 8]),
|
||||||
.phy_4_rx_clk(qsfp1_rx_clk_4_int),
|
.phy_4_rx_clk(eth_rx_clk[1*4+3 +: 1]),
|
||||||
.phy_4_rx_rst(qsfp1_rx_rst_4_int),
|
.phy_4_rx_rst(eth_rx_rst[1*4+3 +: 1]),
|
||||||
.phy_4_xgmii_rxd(qsfp1_rxd_4_int),
|
.phy_4_xgmii_rxd(eth_rxd[(1*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_rxc(qsfp1_rxc_4_int),
|
.phy_4_xgmii_rxc(eth_rxc[(1*4+3)*8 +: 8]),
|
||||||
.phy_4_tx_bad_block(),
|
.phy_4_tx_bad_block(),
|
||||||
.phy_4_rx_error_count(),
|
.phy_4_rx_error_count(),
|
||||||
.phy_4_rx_bad_block(),
|
.phy_4_rx_bad_block(),
|
||||||
@ -610,7 +543,13 @@ qsfp1_phy_inst (
|
|||||||
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
||||||
);
|
);
|
||||||
|
|
||||||
fpga_core
|
fpga_core #(
|
||||||
|
.SW_CNT(4),
|
||||||
|
.LED_CNT(3),
|
||||||
|
.UART_CNT(1),
|
||||||
|
.QSFP_CNT(QSFP_CNT),
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
core_inst (
|
core_inst (
|
||||||
/*
|
/*
|
||||||
* Clock: 156.25 MHz
|
* Clock: 156.25 MHz
|
||||||
@ -618,83 +557,33 @@ core_inst (
|
|||||||
*/
|
*/
|
||||||
.clk(clk_156mhz_int),
|
.clk(clk_156mhz_int),
|
||||||
.rst(rst_156mhz_int),
|
.rst(rst_156mhz_int),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
.sw(sw_int),
|
.sw(sw_int),
|
||||||
.led(led),
|
.led(led),
|
||||||
|
.qsfp_led_act(),
|
||||||
|
.qsfp_led_stat_g(),
|
||||||
|
.qsfp_led_stat_y(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
.uart_txd(uart_txd),
|
||||||
|
.uart_rxd(uart_rxd),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
.qsfp0_tx_clk_1(qsfp0_tx_clk_1_int),
|
.eth_tx_clk(eth_tx_clk),
|
||||||
.qsfp0_tx_rst_1(qsfp0_tx_rst_1_int),
|
.eth_tx_rst(eth_tx_rst),
|
||||||
.qsfp0_txd_1(qsfp0_txd_1_int),
|
.eth_txd(eth_txd),
|
||||||
.qsfp0_txc_1(qsfp0_txc_1_int),
|
.eth_txc(eth_txc),
|
||||||
.qsfp0_rx_clk_1(qsfp0_rx_clk_1_int),
|
.eth_rx_clk(eth_rx_clk),
|
||||||
.qsfp0_rx_rst_1(qsfp0_rx_rst_1_int),
|
.eth_rx_rst(eth_rx_rst),
|
||||||
.qsfp0_rxd_1(qsfp0_rxd_1_int),
|
.eth_rxd(eth_rxd),
|
||||||
.qsfp0_rxc_1(qsfp0_rxc_1_int),
|
.eth_rxc(eth_rxc)
|
||||||
.qsfp0_tx_clk_2(qsfp0_tx_clk_2_int),
|
|
||||||
.qsfp0_tx_rst_2(qsfp0_tx_rst_2_int),
|
|
||||||
.qsfp0_txd_2(qsfp0_txd_2_int),
|
|
||||||
.qsfp0_txc_2(qsfp0_txc_2_int),
|
|
||||||
.qsfp0_rx_clk_2(qsfp0_rx_clk_2_int),
|
|
||||||
.qsfp0_rx_rst_2(qsfp0_rx_rst_2_int),
|
|
||||||
.qsfp0_rxd_2(qsfp0_rxd_2_int),
|
|
||||||
.qsfp0_rxc_2(qsfp0_rxc_2_int),
|
|
||||||
.qsfp0_tx_clk_3(qsfp0_tx_clk_3_int),
|
|
||||||
.qsfp0_tx_rst_3(qsfp0_tx_rst_3_int),
|
|
||||||
.qsfp0_txd_3(qsfp0_txd_3_int),
|
|
||||||
.qsfp0_txc_3(qsfp0_txc_3_int),
|
|
||||||
.qsfp0_rx_clk_3(qsfp0_rx_clk_3_int),
|
|
||||||
.qsfp0_rx_rst_3(qsfp0_rx_rst_3_int),
|
|
||||||
.qsfp0_rxd_3(qsfp0_rxd_3_int),
|
|
||||||
.qsfp0_rxc_3(qsfp0_rxc_3_int),
|
|
||||||
.qsfp0_tx_clk_4(qsfp0_tx_clk_4_int),
|
|
||||||
.qsfp0_tx_rst_4(qsfp0_tx_rst_4_int),
|
|
||||||
.qsfp0_txd_4(qsfp0_txd_4_int),
|
|
||||||
.qsfp0_txc_4(qsfp0_txc_4_int),
|
|
||||||
.qsfp0_rx_clk_4(qsfp0_rx_clk_4_int),
|
|
||||||
.qsfp0_rx_rst_4(qsfp0_rx_rst_4_int),
|
|
||||||
.qsfp0_rxd_4(qsfp0_rxd_4_int),
|
|
||||||
.qsfp0_rxc_4(qsfp0_rxc_4_int),
|
|
||||||
.qsfp1_tx_clk_1(qsfp1_tx_clk_1_int),
|
|
||||||
.qsfp1_tx_rst_1(qsfp1_tx_rst_1_int),
|
|
||||||
.qsfp1_txd_1(qsfp1_txd_1_int),
|
|
||||||
.qsfp1_txc_1(qsfp1_txc_1_int),
|
|
||||||
.qsfp1_rx_clk_1(qsfp1_rx_clk_1_int),
|
|
||||||
.qsfp1_rx_rst_1(qsfp1_rx_rst_1_int),
|
|
||||||
.qsfp1_rxd_1(qsfp1_rxd_1_int),
|
|
||||||
.qsfp1_rxc_1(qsfp1_rxc_1_int),
|
|
||||||
.qsfp1_tx_clk_2(qsfp1_tx_clk_2_int),
|
|
||||||
.qsfp1_tx_rst_2(qsfp1_tx_rst_2_int),
|
|
||||||
.qsfp1_txd_2(qsfp1_txd_2_int),
|
|
||||||
.qsfp1_txc_2(qsfp1_txc_2_int),
|
|
||||||
.qsfp1_rx_clk_2(qsfp1_rx_clk_2_int),
|
|
||||||
.qsfp1_rx_rst_2(qsfp1_rx_rst_2_int),
|
|
||||||
.qsfp1_rxd_2(qsfp1_rxd_2_int),
|
|
||||||
.qsfp1_rxc_2(qsfp1_rxc_2_int),
|
|
||||||
.qsfp1_tx_clk_3(qsfp1_tx_clk_3_int),
|
|
||||||
.qsfp1_tx_rst_3(qsfp1_tx_rst_3_int),
|
|
||||||
.qsfp1_txd_3(qsfp1_txd_3_int),
|
|
||||||
.qsfp1_txc_3(qsfp1_txc_3_int),
|
|
||||||
.qsfp1_rx_clk_3(qsfp1_rx_clk_3_int),
|
|
||||||
.qsfp1_rx_rst_3(qsfp1_rx_rst_3_int),
|
|
||||||
.qsfp1_rxd_3(qsfp1_rxd_3_int),
|
|
||||||
.qsfp1_rxc_3(qsfp1_rxc_3_int),
|
|
||||||
.qsfp1_tx_clk_4(qsfp1_tx_clk_4_int),
|
|
||||||
.qsfp1_tx_rst_4(qsfp1_tx_rst_4_int),
|
|
||||||
.qsfp1_txd_4(qsfp1_txd_4_int),
|
|
||||||
.qsfp1_txc_4(qsfp1_txc_4_int),
|
|
||||||
.qsfp1_rx_clk_4(qsfp1_rx_clk_4_int),
|
|
||||||
.qsfp1_rx_rst_4(qsfp1_rx_rst_4_int),
|
|
||||||
.qsfp1_rxd_4(qsfp1_rxd_4_int),
|
|
||||||
.qsfp1_rxc_4(qsfp1_rxc_4_int),
|
|
||||||
/*
|
|
||||||
* UART: 115200 bps, 8N1
|
|
||||||
*/
|
|
||||||
.uart_rxd(uart_rxd),
|
|
||||||
.uart_txd(uart_txd_int)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@ -42,6 +42,12 @@ module fpga (
|
|||||||
*/
|
*/
|
||||||
output wire hbm_cattrip,
|
output wire hbm_cattrip,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
output wire uart_txd,
|
||||||
|
input wire uart_rxd,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
@ -162,47 +168,25 @@ sync_reset_125mhz_inst (
|
|||||||
assign hbm_cattrip = 1'b0;
|
assign hbm_cattrip = 1'b0;
|
||||||
|
|
||||||
// XGMII 10G PHY
|
// XGMII 10G PHY
|
||||||
|
localparam QSFP_CNT = 2;
|
||||||
|
localparam CH_CNT = QSFP_CNT*4;
|
||||||
|
|
||||||
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_txc;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_rxd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_rxc;
|
||||||
|
|
||||||
|
assign clk_156mhz_int = eth_tx_clk[0];
|
||||||
|
assign rst_156mhz_int = eth_tx_rst[0];
|
||||||
|
|
||||||
// QSFP0
|
// QSFP0
|
||||||
assign qsfp0_refclk_oe_b = 1'b0;
|
assign qsfp0_refclk_oe_b = 1'b0;
|
||||||
assign qsfp0_refclk_fs = 1'b1;
|
assign qsfp0_refclk_fs = 1'b1;
|
||||||
|
|
||||||
wire qsfp0_tx_clk_1_int;
|
|
||||||
wire qsfp0_tx_rst_1_int;
|
|
||||||
wire [63:0] qsfp0_txd_1_int;
|
|
||||||
wire [7:0] qsfp0_txc_1_int;
|
|
||||||
wire qsfp0_rx_clk_1_int;
|
|
||||||
wire qsfp0_rx_rst_1_int;
|
|
||||||
wire [63:0] qsfp0_rxd_1_int;
|
|
||||||
wire [7:0] qsfp0_rxc_1_int;
|
|
||||||
wire qsfp0_tx_clk_2_int;
|
|
||||||
wire qsfp0_tx_rst_2_int;
|
|
||||||
wire [63:0] qsfp0_txd_2_int;
|
|
||||||
wire [7:0] qsfp0_txc_2_int;
|
|
||||||
wire qsfp0_rx_clk_2_int;
|
|
||||||
wire qsfp0_rx_rst_2_int;
|
|
||||||
wire [63:0] qsfp0_rxd_2_int;
|
|
||||||
wire [7:0] qsfp0_rxc_2_int;
|
|
||||||
wire qsfp0_tx_clk_3_int;
|
|
||||||
wire qsfp0_tx_rst_3_int;
|
|
||||||
wire [63:0] qsfp0_txd_3_int;
|
|
||||||
wire [7:0] qsfp0_txc_3_int;
|
|
||||||
wire qsfp0_rx_clk_3_int;
|
|
||||||
wire qsfp0_rx_rst_3_int;
|
|
||||||
wire [63:0] qsfp0_rxd_3_int;
|
|
||||||
wire [7:0] qsfp0_rxc_3_int;
|
|
||||||
wire qsfp0_tx_clk_4_int;
|
|
||||||
wire qsfp0_tx_rst_4_int;
|
|
||||||
wire [63:0] qsfp0_txd_4_int;
|
|
||||||
wire [7:0] qsfp0_txc_4_int;
|
|
||||||
wire qsfp0_rx_clk_4_int;
|
|
||||||
wire qsfp0_rx_rst_4_int;
|
|
||||||
wire [63:0] qsfp0_rxd_4_int;
|
|
||||||
wire [7:0] qsfp0_rxc_4_int;
|
|
||||||
|
|
||||||
assign clk_156mhz_int = qsfp0_tx_clk_1_int;
|
|
||||||
assign rst_156mhz_int = qsfp0_tx_rst_1_int;
|
|
||||||
|
|
||||||
wire qsfp0_rx_block_lock_1;
|
wire qsfp0_rx_block_lock_1;
|
||||||
wire qsfp0_rx_block_lock_2;
|
wire qsfp0_rx_block_lock_2;
|
||||||
wire qsfp0_rx_block_lock_3;
|
wire qsfp0_rx_block_lock_3;
|
||||||
@ -264,14 +248,14 @@ qsfp0_phy_inst (
|
|||||||
/*
|
/*
|
||||||
* PHY connections
|
* PHY connections
|
||||||
*/
|
*/
|
||||||
.phy_1_tx_clk(qsfp0_tx_clk_1_int),
|
.phy_1_tx_clk(eth_tx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_tx_rst(qsfp0_tx_rst_1_int),
|
.phy_1_tx_rst(eth_tx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_txd(qsfp0_txd_1_int),
|
.phy_1_xgmii_txd(eth_txd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_txc(qsfp0_txc_1_int),
|
.phy_1_xgmii_txc(eth_txc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_rx_clk(qsfp0_rx_clk_1_int),
|
.phy_1_rx_clk(eth_rx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_rx_rst(qsfp0_rx_rst_1_int),
|
.phy_1_rx_rst(eth_rx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_rxd(qsfp0_rxd_1_int),
|
.phy_1_xgmii_rxd(eth_rxd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_rxc(qsfp0_rxc_1_int),
|
.phy_1_xgmii_rxc(eth_rxc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_tx_bad_block(),
|
.phy_1_tx_bad_block(),
|
||||||
.phy_1_rx_error_count(),
|
.phy_1_rx_error_count(),
|
||||||
.phy_1_rx_bad_block(),
|
.phy_1_rx_bad_block(),
|
||||||
@ -281,14 +265,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_2_tx_clk(qsfp0_tx_clk_2_int),
|
.phy_2_tx_clk(eth_tx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_tx_rst(qsfp0_tx_rst_2_int),
|
.phy_2_tx_rst(eth_tx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_txd(qsfp0_txd_2_int),
|
.phy_2_xgmii_txd(eth_txd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_txc(qsfp0_txc_2_int),
|
.phy_2_xgmii_txc(eth_txc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_rx_clk(qsfp0_rx_clk_2_int),
|
.phy_2_rx_clk(eth_rx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_rx_rst(qsfp0_rx_rst_2_int),
|
.phy_2_rx_rst(eth_rx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_rxd(qsfp0_rxd_2_int),
|
.phy_2_xgmii_rxd(eth_rxd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_rxc(qsfp0_rxc_2_int),
|
.phy_2_xgmii_rxc(eth_rxc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_tx_bad_block(),
|
.phy_2_tx_bad_block(),
|
||||||
.phy_2_rx_error_count(),
|
.phy_2_rx_error_count(),
|
||||||
.phy_2_rx_bad_block(),
|
.phy_2_rx_bad_block(),
|
||||||
@ -298,14 +282,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_3_tx_clk(qsfp0_tx_clk_3_int),
|
.phy_3_tx_clk(eth_tx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_tx_rst(qsfp0_tx_rst_3_int),
|
.phy_3_tx_rst(eth_tx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_txd(qsfp0_txd_3_int),
|
.phy_3_xgmii_txd(eth_txd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_txc(qsfp0_txc_3_int),
|
.phy_3_xgmii_txc(eth_txc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_rx_clk(qsfp0_rx_clk_3_int),
|
.phy_3_rx_clk(eth_rx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_rx_rst(qsfp0_rx_rst_3_int),
|
.phy_3_rx_rst(eth_rx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_rxd(qsfp0_rxd_3_int),
|
.phy_3_xgmii_rxd(eth_rxd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_rxc(qsfp0_rxc_3_int),
|
.phy_3_xgmii_rxc(eth_rxc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_tx_bad_block(),
|
.phy_3_tx_bad_block(),
|
||||||
.phy_3_rx_error_count(),
|
.phy_3_rx_error_count(),
|
||||||
.phy_3_rx_bad_block(),
|
.phy_3_rx_bad_block(),
|
||||||
@ -315,14 +299,14 @@ qsfp0_phy_inst (
|
|||||||
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_4_tx_clk(qsfp0_tx_clk_4_int),
|
.phy_4_tx_clk(eth_tx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_tx_rst(qsfp0_tx_rst_4_int),
|
.phy_4_tx_rst(eth_tx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_txd(qsfp0_txd_4_int),
|
.phy_4_xgmii_txd(eth_txd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_txc(qsfp0_txc_4_int),
|
.phy_4_xgmii_txc(eth_txc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_rx_clk(qsfp0_rx_clk_4_int),
|
.phy_4_rx_clk(eth_rx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_rx_rst(qsfp0_rx_rst_4_int),
|
.phy_4_rx_rst(eth_rx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_rxd(qsfp0_rxd_4_int),
|
.phy_4_xgmii_rxd(eth_rxd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_rxc(qsfp0_rxc_4_int),
|
.phy_4_xgmii_rxc(eth_rxc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_tx_bad_block(),
|
.phy_4_tx_bad_block(),
|
||||||
.phy_4_rx_error_count(),
|
.phy_4_rx_error_count(),
|
||||||
.phy_4_rx_bad_block(),
|
.phy_4_rx_bad_block(),
|
||||||
@ -337,39 +321,6 @@ qsfp0_phy_inst (
|
|||||||
assign qsfp1_refclk_oe_b = 1'b0;
|
assign qsfp1_refclk_oe_b = 1'b0;
|
||||||
assign qsfp1_refclk_fs = 1'b1;
|
assign qsfp1_refclk_fs = 1'b1;
|
||||||
|
|
||||||
wire qsfp1_tx_clk_1_int;
|
|
||||||
wire qsfp1_tx_rst_1_int;
|
|
||||||
wire [63:0] qsfp1_txd_1_int;
|
|
||||||
wire [7:0] qsfp1_txc_1_int;
|
|
||||||
wire qsfp1_rx_clk_1_int;
|
|
||||||
wire qsfp1_rx_rst_1_int;
|
|
||||||
wire [63:0] qsfp1_rxd_1_int;
|
|
||||||
wire [7:0] qsfp1_rxc_1_int;
|
|
||||||
wire qsfp1_tx_clk_2_int;
|
|
||||||
wire qsfp1_tx_rst_2_int;
|
|
||||||
wire [63:0] qsfp1_txd_2_int;
|
|
||||||
wire [7:0] qsfp1_txc_2_int;
|
|
||||||
wire qsfp1_rx_clk_2_int;
|
|
||||||
wire qsfp1_rx_rst_2_int;
|
|
||||||
wire [63:0] qsfp1_rxd_2_int;
|
|
||||||
wire [7:0] qsfp1_rxc_2_int;
|
|
||||||
wire qsfp1_tx_clk_3_int;
|
|
||||||
wire qsfp1_tx_rst_3_int;
|
|
||||||
wire [63:0] qsfp1_txd_3_int;
|
|
||||||
wire [7:0] qsfp1_txc_3_int;
|
|
||||||
wire qsfp1_rx_clk_3_int;
|
|
||||||
wire qsfp1_rx_rst_3_int;
|
|
||||||
wire [63:0] qsfp1_rxd_3_int;
|
|
||||||
wire [7:0] qsfp1_rxc_3_int;
|
|
||||||
wire qsfp1_tx_clk_4_int;
|
|
||||||
wire qsfp1_tx_rst_4_int;
|
|
||||||
wire [63:0] qsfp1_txd_4_int;
|
|
||||||
wire [7:0] qsfp1_txc_4_int;
|
|
||||||
wire qsfp1_rx_clk_4_int;
|
|
||||||
wire qsfp1_rx_rst_4_int;
|
|
||||||
wire [63:0] qsfp1_rxd_4_int;
|
|
||||||
wire [7:0] qsfp1_rxc_4_int;
|
|
||||||
|
|
||||||
wire qsfp1_rx_block_lock_1;
|
wire qsfp1_rx_block_lock_1;
|
||||||
wire qsfp1_rx_block_lock_2;
|
wire qsfp1_rx_block_lock_2;
|
||||||
wire qsfp1_rx_block_lock_3;
|
wire qsfp1_rx_block_lock_3;
|
||||||
@ -415,14 +366,14 @@ qsfp1_phy_inst (
|
|||||||
/*
|
/*
|
||||||
* PHY connections
|
* PHY connections
|
||||||
*/
|
*/
|
||||||
.phy_1_tx_clk(qsfp1_tx_clk_1_int),
|
.phy_1_tx_clk(eth_tx_clk[1*4+0 +: 1]),
|
||||||
.phy_1_tx_rst(qsfp1_tx_rst_1_int),
|
.phy_1_tx_rst(eth_tx_rst[1*4+0 +: 1]),
|
||||||
.phy_1_xgmii_txd(qsfp1_txd_1_int),
|
.phy_1_xgmii_txd(eth_txd[(1*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_txc(qsfp1_txc_1_int),
|
.phy_1_xgmii_txc(eth_txc[(1*4+0)*8 +: 8]),
|
||||||
.phy_1_rx_clk(qsfp1_rx_clk_1_int),
|
.phy_1_rx_clk(eth_rx_clk[1*4+0 +: 1]),
|
||||||
.phy_1_rx_rst(qsfp1_rx_rst_1_int),
|
.phy_1_rx_rst(eth_rx_rst[1*4+0 +: 1]),
|
||||||
.phy_1_xgmii_rxd(qsfp1_rxd_1_int),
|
.phy_1_xgmii_rxd(eth_rxd[(1*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_rxc(qsfp1_rxc_1_int),
|
.phy_1_xgmii_rxc(eth_rxc[(1*4+0)*8 +: 8]),
|
||||||
.phy_1_tx_bad_block(),
|
.phy_1_tx_bad_block(),
|
||||||
.phy_1_rx_error_count(),
|
.phy_1_rx_error_count(),
|
||||||
.phy_1_rx_bad_block(),
|
.phy_1_rx_bad_block(),
|
||||||
@ -432,14 +383,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_2_tx_clk(qsfp1_tx_clk_2_int),
|
.phy_2_tx_clk(eth_tx_clk[1*4+1 +: 1]),
|
||||||
.phy_2_tx_rst(qsfp1_tx_rst_2_int),
|
.phy_2_tx_rst(eth_tx_rst[1*4+1 +: 1]),
|
||||||
.phy_2_xgmii_txd(qsfp1_txd_2_int),
|
.phy_2_xgmii_txd(eth_txd[(1*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_txc(qsfp1_txc_2_int),
|
.phy_2_xgmii_txc(eth_txc[(1*4+1)*8 +: 8]),
|
||||||
.phy_2_rx_clk(qsfp1_rx_clk_2_int),
|
.phy_2_rx_clk(eth_rx_clk[1*4+1 +: 1]),
|
||||||
.phy_2_rx_rst(qsfp1_rx_rst_2_int),
|
.phy_2_rx_rst(eth_rx_rst[1*4+1 +: 1]),
|
||||||
.phy_2_xgmii_rxd(qsfp1_rxd_2_int),
|
.phy_2_xgmii_rxd(eth_rxd[(1*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_rxc(qsfp1_rxc_2_int),
|
.phy_2_xgmii_rxc(eth_rxc[(1*4+1)*8 +: 8]),
|
||||||
.phy_2_tx_bad_block(),
|
.phy_2_tx_bad_block(),
|
||||||
.phy_2_rx_error_count(),
|
.phy_2_rx_error_count(),
|
||||||
.phy_2_rx_bad_block(),
|
.phy_2_rx_bad_block(),
|
||||||
@ -449,14 +400,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_3_tx_clk(qsfp1_tx_clk_3_int),
|
.phy_3_tx_clk(eth_tx_clk[1*4+2 +: 1]),
|
||||||
.phy_3_tx_rst(qsfp1_tx_rst_3_int),
|
.phy_3_tx_rst(eth_tx_rst[1*4+2 +: 1]),
|
||||||
.phy_3_xgmii_txd(qsfp1_txd_3_int),
|
.phy_3_xgmii_txd(eth_txd[(1*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_txc(qsfp1_txc_3_int),
|
.phy_3_xgmii_txc(eth_txc[(1*4+2)*8 +: 8]),
|
||||||
.phy_3_rx_clk(qsfp1_rx_clk_3_int),
|
.phy_3_rx_clk(eth_rx_clk[1*4+2 +: 1]),
|
||||||
.phy_3_rx_rst(qsfp1_rx_rst_3_int),
|
.phy_3_rx_rst(eth_rx_rst[1*4+2 +: 1]),
|
||||||
.phy_3_xgmii_rxd(qsfp1_rxd_3_int),
|
.phy_3_xgmii_rxd(eth_rxd[(1*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_rxc(qsfp1_rxc_3_int),
|
.phy_3_xgmii_rxc(eth_rxc[(1*4+2)*8 +: 8]),
|
||||||
.phy_3_tx_bad_block(),
|
.phy_3_tx_bad_block(),
|
||||||
.phy_3_rx_error_count(),
|
.phy_3_rx_error_count(),
|
||||||
.phy_3_rx_bad_block(),
|
.phy_3_rx_bad_block(),
|
||||||
@ -466,14 +417,14 @@ qsfp1_phy_inst (
|
|||||||
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_4_tx_clk(qsfp1_tx_clk_4_int),
|
.phy_4_tx_clk(eth_tx_clk[1*4+3 +: 1]),
|
||||||
.phy_4_tx_rst(qsfp1_tx_rst_4_int),
|
.phy_4_tx_rst(eth_tx_rst[1*4+3 +: 1]),
|
||||||
.phy_4_xgmii_txd(qsfp1_txd_4_int),
|
.phy_4_xgmii_txd(eth_txd[(1*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_txc(qsfp1_txc_4_int),
|
.phy_4_xgmii_txc(eth_txc[(1*4+3)*8 +: 8]),
|
||||||
.phy_4_rx_clk(qsfp1_rx_clk_4_int),
|
.phy_4_rx_clk(eth_rx_clk[1*4+3 +: 1]),
|
||||||
.phy_4_rx_rst(qsfp1_rx_rst_4_int),
|
.phy_4_rx_rst(eth_rx_rst[1*4+3 +: 1]),
|
||||||
.phy_4_xgmii_rxd(qsfp1_rxd_4_int),
|
.phy_4_xgmii_rxd(eth_rxd[(1*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_rxc(qsfp1_rxc_4_int),
|
.phy_4_xgmii_rxc(eth_rxc[(1*4+3)*8 +: 8]),
|
||||||
.phy_4_tx_bad_block(),
|
.phy_4_tx_bad_block(),
|
||||||
.phy_4_rx_error_count(),
|
.phy_4_rx_error_count(),
|
||||||
.phy_4_rx_bad_block(),
|
.phy_4_rx_bad_block(),
|
||||||
@ -484,7 +435,11 @@ qsfp1_phy_inst (
|
|||||||
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
||||||
);
|
);
|
||||||
|
|
||||||
fpga_core
|
fpga_core #(
|
||||||
|
.UART_CNT(1),
|
||||||
|
.QSFP_CNT(QSFP_CNT),
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
core_inst (
|
core_inst (
|
||||||
/*
|
/*
|
||||||
* Clock: 156.25 MHz
|
* Clock: 156.25 MHz
|
||||||
@ -492,73 +447,33 @@ core_inst (
|
|||||||
*/
|
*/
|
||||||
.clk(clk_156mhz_int),
|
.clk(clk_156mhz_int),
|
||||||
.rst(rst_156mhz_int),
|
.rst(rst_156mhz_int),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO
|
||||||
|
*/
|
||||||
|
.sw(0),
|
||||||
|
.led(),
|
||||||
|
.qsfp_led_act(),
|
||||||
|
.qsfp_led_stat_g(),
|
||||||
|
.qsfp_led_stat_y(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
.uart_txd(uart_txd),
|
||||||
|
.uart_rxd(uart_rxd),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
.qsfp0_tx_clk_1(qsfp0_tx_clk_1_int),
|
.eth_tx_clk(eth_tx_clk),
|
||||||
.qsfp0_tx_rst_1(qsfp0_tx_rst_1_int),
|
.eth_tx_rst(eth_tx_rst),
|
||||||
.qsfp0_txd_1(qsfp0_txd_1_int),
|
.eth_txd(eth_txd),
|
||||||
.qsfp0_txc_1(qsfp0_txc_1_int),
|
.eth_txc(eth_txc),
|
||||||
.qsfp0_rx_clk_1(qsfp0_rx_clk_1_int),
|
.eth_rx_clk(eth_rx_clk),
|
||||||
.qsfp0_rx_rst_1(qsfp0_rx_rst_1_int),
|
.eth_rx_rst(eth_rx_rst),
|
||||||
.qsfp0_rxd_1(qsfp0_rxd_1_int),
|
.eth_rxd(eth_rxd),
|
||||||
.qsfp0_rxc_1(qsfp0_rxc_1_int),
|
.eth_rxc(eth_rxc)
|
||||||
.qsfp0_tx_clk_2(qsfp0_tx_clk_2_int),
|
|
||||||
.qsfp0_tx_rst_2(qsfp0_tx_rst_2_int),
|
|
||||||
.qsfp0_txd_2(qsfp0_txd_2_int),
|
|
||||||
.qsfp0_txc_2(qsfp0_txc_2_int),
|
|
||||||
.qsfp0_rx_clk_2(qsfp0_rx_clk_2_int),
|
|
||||||
.qsfp0_rx_rst_2(qsfp0_rx_rst_2_int),
|
|
||||||
.qsfp0_rxd_2(qsfp0_rxd_2_int),
|
|
||||||
.qsfp0_rxc_2(qsfp0_rxc_2_int),
|
|
||||||
.qsfp0_tx_clk_3(qsfp0_tx_clk_3_int),
|
|
||||||
.qsfp0_tx_rst_3(qsfp0_tx_rst_3_int),
|
|
||||||
.qsfp0_txd_3(qsfp0_txd_3_int),
|
|
||||||
.qsfp0_txc_3(qsfp0_txc_3_int),
|
|
||||||
.qsfp0_rx_clk_3(qsfp0_rx_clk_3_int),
|
|
||||||
.qsfp0_rx_rst_3(qsfp0_rx_rst_3_int),
|
|
||||||
.qsfp0_rxd_3(qsfp0_rxd_3_int),
|
|
||||||
.qsfp0_rxc_3(qsfp0_rxc_3_int),
|
|
||||||
.qsfp0_tx_clk_4(qsfp0_tx_clk_4_int),
|
|
||||||
.qsfp0_tx_rst_4(qsfp0_tx_rst_4_int),
|
|
||||||
.qsfp0_txd_4(qsfp0_txd_4_int),
|
|
||||||
.qsfp0_txc_4(qsfp0_txc_4_int),
|
|
||||||
.qsfp0_rx_clk_4(qsfp0_rx_clk_4_int),
|
|
||||||
.qsfp0_rx_rst_4(qsfp0_rx_rst_4_int),
|
|
||||||
.qsfp0_rxd_4(qsfp0_rxd_4_int),
|
|
||||||
.qsfp0_rxc_4(qsfp0_rxc_4_int),
|
|
||||||
.qsfp1_tx_clk_1(qsfp1_tx_clk_1_int),
|
|
||||||
.qsfp1_tx_rst_1(qsfp1_tx_rst_1_int),
|
|
||||||
.qsfp1_txd_1(qsfp1_txd_1_int),
|
|
||||||
.qsfp1_txc_1(qsfp1_txc_1_int),
|
|
||||||
.qsfp1_rx_clk_1(qsfp1_rx_clk_1_int),
|
|
||||||
.qsfp1_rx_rst_1(qsfp1_rx_rst_1_int),
|
|
||||||
.qsfp1_rxd_1(qsfp1_rxd_1_int),
|
|
||||||
.qsfp1_rxc_1(qsfp1_rxc_1_int),
|
|
||||||
.qsfp1_tx_clk_2(qsfp1_tx_clk_2_int),
|
|
||||||
.qsfp1_tx_rst_2(qsfp1_tx_rst_2_int),
|
|
||||||
.qsfp1_txd_2(qsfp1_txd_2_int),
|
|
||||||
.qsfp1_txc_2(qsfp1_txc_2_int),
|
|
||||||
.qsfp1_rx_clk_2(qsfp1_rx_clk_2_int),
|
|
||||||
.qsfp1_rx_rst_2(qsfp1_rx_rst_2_int),
|
|
||||||
.qsfp1_rxd_2(qsfp1_rxd_2_int),
|
|
||||||
.qsfp1_rxc_2(qsfp1_rxc_2_int),
|
|
||||||
.qsfp1_tx_clk_3(qsfp1_tx_clk_3_int),
|
|
||||||
.qsfp1_tx_rst_3(qsfp1_tx_rst_3_int),
|
|
||||||
.qsfp1_txd_3(qsfp1_txd_3_int),
|
|
||||||
.qsfp1_txc_3(qsfp1_txc_3_int),
|
|
||||||
.qsfp1_rx_clk_3(qsfp1_rx_clk_3_int),
|
|
||||||
.qsfp1_rx_rst_3(qsfp1_rx_rst_3_int),
|
|
||||||
.qsfp1_rxd_3(qsfp1_rxd_3_int),
|
|
||||||
.qsfp1_rxc_3(qsfp1_rxc_3_int),
|
|
||||||
.qsfp1_tx_clk_4(qsfp1_tx_clk_4_int),
|
|
||||||
.qsfp1_tx_rst_4(qsfp1_tx_rst_4_int),
|
|
||||||
.qsfp1_txd_4(qsfp1_txd_4_int),
|
|
||||||
.qsfp1_txc_4(qsfp1_txc_4_int),
|
|
||||||
.qsfp1_rx_clk_4(qsfp1_rx_clk_4_int),
|
|
||||||
.qsfp1_rx_rst_4(qsfp1_rx_rst_4_int),
|
|
||||||
.qsfp1_rxd_4(qsfp1_rxd_4_int),
|
|
||||||
.qsfp1_rxc_4(qsfp1_rxc_4_int)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@ -31,15 +31,26 @@ THE SOFTWARE.
|
|||||||
/*
|
/*
|
||||||
* FPGA top-level module
|
* FPGA top-level module
|
||||||
*/
|
*/
|
||||||
module fpga (
|
module fpga #
|
||||||
|
(
|
||||||
|
parameter QSFP_CNT = 1,
|
||||||
|
parameter UART_CNT = 3
|
||||||
|
)
|
||||||
|
(
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
output wire qsfp_led_act,
|
output wire [QSFP_CNT-1:0] qsfp_led_act,
|
||||||
output wire qsfp_led_stat_g,
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_g,
|
||||||
output wire qsfp_led_stat_y,
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_y,
|
||||||
output wire hbm_cattrip,
|
output wire hbm_cattrip,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
output wire [UART_CNT-1:0] uart_txd,
|
||||||
|
input wire [UART_CNT-1:0] uart_rxd,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
@ -147,41 +158,19 @@ sync_reset_125mhz_inst (
|
|||||||
assign hbm_cattrip = 1'b0;
|
assign hbm_cattrip = 1'b0;
|
||||||
|
|
||||||
// XGMII 10G PHY
|
// XGMII 10G PHY
|
||||||
wire qsfp_tx_clk_1_int;
|
localparam CH_CNT = QSFP_CNT*4;
|
||||||
wire qsfp_tx_rst_1_int;
|
|
||||||
wire [63:0] qsfp_txd_1_int;
|
|
||||||
wire [7:0] qsfp_txc_1_int;
|
|
||||||
wire qsfp_rx_clk_1_int;
|
|
||||||
wire qsfp_rx_rst_1_int;
|
|
||||||
wire [63:0] qsfp_rxd_1_int;
|
|
||||||
wire [7:0] qsfp_rxc_1_int;
|
|
||||||
wire qsfp_tx_clk_2_int;
|
|
||||||
wire qsfp_tx_rst_2_int;
|
|
||||||
wire [63:0] qsfp_txd_2_int;
|
|
||||||
wire [7:0] qsfp_txc_2_int;
|
|
||||||
wire qsfp_rx_clk_2_int;
|
|
||||||
wire qsfp_rx_rst_2_int;
|
|
||||||
wire [63:0] qsfp_rxd_2_int;
|
|
||||||
wire [7:0] qsfp_rxc_2_int;
|
|
||||||
wire qsfp_tx_clk_3_int;
|
|
||||||
wire qsfp_tx_rst_3_int;
|
|
||||||
wire [63:0] qsfp_txd_3_int;
|
|
||||||
wire [7:0] qsfp_txc_3_int;
|
|
||||||
wire qsfp_rx_clk_3_int;
|
|
||||||
wire qsfp_rx_rst_3_int;
|
|
||||||
wire [63:0] qsfp_rxd_3_int;
|
|
||||||
wire [7:0] qsfp_rxc_3_int;
|
|
||||||
wire qsfp_tx_clk_4_int;
|
|
||||||
wire qsfp_tx_rst_4_int;
|
|
||||||
wire [63:0] qsfp_txd_4_int;
|
|
||||||
wire [7:0] qsfp_txc_4_int;
|
|
||||||
wire qsfp_rx_clk_4_int;
|
|
||||||
wire qsfp_rx_rst_4_int;
|
|
||||||
wire [63:0] qsfp_rxd_4_int;
|
|
||||||
wire [7:0] qsfp_rxc_4_int;
|
|
||||||
|
|
||||||
assign clk_156mhz_int = qsfp_tx_clk_1_int;
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
assign rst_156mhz_int = qsfp_tx_rst_1_int;
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_txc;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_rxd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_rxc;
|
||||||
|
|
||||||
|
assign clk_156mhz_int = eth_tx_clk[0];
|
||||||
|
assign rst_156mhz_int = eth_tx_rst[0];
|
||||||
|
|
||||||
wire qsfp_rx_block_lock_1;
|
wire qsfp_rx_block_lock_1;
|
||||||
wire qsfp_rx_block_lock_2;
|
wire qsfp_rx_block_lock_2;
|
||||||
@ -244,14 +233,14 @@ qsfp_phy_inst (
|
|||||||
/*
|
/*
|
||||||
* PHY connections
|
* PHY connections
|
||||||
*/
|
*/
|
||||||
.phy_1_tx_clk(qsfp_tx_clk_1_int),
|
.phy_1_tx_clk(eth_tx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_tx_rst(qsfp_tx_rst_1_int),
|
.phy_1_tx_rst(eth_tx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_txd(qsfp_txd_1_int),
|
.phy_1_xgmii_txd(eth_txd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_txc(qsfp_txc_1_int),
|
.phy_1_xgmii_txc(eth_txc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_rx_clk(qsfp_rx_clk_1_int),
|
.phy_1_rx_clk(eth_rx_clk[0*4+0 +: 1]),
|
||||||
.phy_1_rx_rst(qsfp_rx_rst_1_int),
|
.phy_1_rx_rst(eth_rx_rst[0*4+0 +: 1]),
|
||||||
.phy_1_xgmii_rxd(qsfp_rxd_1_int),
|
.phy_1_xgmii_rxd(eth_rxd[(0*4+0)*64 +: 64]),
|
||||||
.phy_1_xgmii_rxc(qsfp_rxc_1_int),
|
.phy_1_xgmii_rxc(eth_rxc[(0*4+0)*8 +: 8]),
|
||||||
.phy_1_tx_bad_block(),
|
.phy_1_tx_bad_block(),
|
||||||
.phy_1_rx_error_count(),
|
.phy_1_rx_error_count(),
|
||||||
.phy_1_rx_bad_block(),
|
.phy_1_rx_bad_block(),
|
||||||
@ -261,14 +250,14 @@ qsfp_phy_inst (
|
|||||||
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_2_tx_clk(qsfp_tx_clk_2_int),
|
.phy_2_tx_clk(eth_tx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_tx_rst(qsfp_tx_rst_2_int),
|
.phy_2_tx_rst(eth_tx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_txd(qsfp_txd_2_int),
|
.phy_2_xgmii_txd(eth_txd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_txc(qsfp_txc_2_int),
|
.phy_2_xgmii_txc(eth_txc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_rx_clk(qsfp_rx_clk_2_int),
|
.phy_2_rx_clk(eth_rx_clk[0*4+1 +: 1]),
|
||||||
.phy_2_rx_rst(qsfp_rx_rst_2_int),
|
.phy_2_rx_rst(eth_rx_rst[0*4+1 +: 1]),
|
||||||
.phy_2_xgmii_rxd(qsfp_rxd_2_int),
|
.phy_2_xgmii_rxd(eth_rxd[(0*4+1)*64 +: 64]),
|
||||||
.phy_2_xgmii_rxc(qsfp_rxc_2_int),
|
.phy_2_xgmii_rxc(eth_rxc[(0*4+1)*8 +: 8]),
|
||||||
.phy_2_tx_bad_block(),
|
.phy_2_tx_bad_block(),
|
||||||
.phy_2_rx_error_count(),
|
.phy_2_rx_error_count(),
|
||||||
.phy_2_rx_bad_block(),
|
.phy_2_rx_bad_block(),
|
||||||
@ -278,14 +267,14 @@ qsfp_phy_inst (
|
|||||||
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_3_tx_clk(qsfp_tx_clk_3_int),
|
.phy_3_tx_clk(eth_tx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_tx_rst(qsfp_tx_rst_3_int),
|
.phy_3_tx_rst(eth_tx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_txd(qsfp_txd_3_int),
|
.phy_3_xgmii_txd(eth_txd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_txc(qsfp_txc_3_int),
|
.phy_3_xgmii_txc(eth_txc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_rx_clk(qsfp_rx_clk_3_int),
|
.phy_3_rx_clk(eth_rx_clk[0*4+2 +: 1]),
|
||||||
.phy_3_rx_rst(qsfp_rx_rst_3_int),
|
.phy_3_rx_rst(eth_rx_rst[0*4+2 +: 1]),
|
||||||
.phy_3_xgmii_rxd(qsfp_rxd_3_int),
|
.phy_3_xgmii_rxd(eth_rxd[(0*4+2)*64 +: 64]),
|
||||||
.phy_3_xgmii_rxc(qsfp_rxc_3_int),
|
.phy_3_xgmii_rxc(eth_rxc[(0*4+2)*8 +: 8]),
|
||||||
.phy_3_tx_bad_block(),
|
.phy_3_tx_bad_block(),
|
||||||
.phy_3_rx_error_count(),
|
.phy_3_rx_error_count(),
|
||||||
.phy_3_rx_bad_block(),
|
.phy_3_rx_bad_block(),
|
||||||
@ -295,14 +284,14 @@ qsfp_phy_inst (
|
|||||||
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
.phy_4_tx_clk(qsfp_tx_clk_4_int),
|
.phy_4_tx_clk(eth_tx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_tx_rst(qsfp_tx_rst_4_int),
|
.phy_4_tx_rst(eth_tx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_txd(qsfp_txd_4_int),
|
.phy_4_xgmii_txd(eth_txd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_txc(qsfp_txc_4_int),
|
.phy_4_xgmii_txc(eth_txc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_rx_clk(qsfp_rx_clk_4_int),
|
.phy_4_rx_clk(eth_rx_clk[0*4+3 +: 1]),
|
||||||
.phy_4_rx_rst(qsfp_rx_rst_4_int),
|
.phy_4_rx_rst(eth_rx_rst[0*4+3 +: 1]),
|
||||||
.phy_4_xgmii_rxd(qsfp_rxd_4_int),
|
.phy_4_xgmii_rxd(eth_rxd[(0*4+3)*64 +: 64]),
|
||||||
.phy_4_xgmii_rxc(qsfp_rxc_4_int),
|
.phy_4_xgmii_rxc(eth_rxc[(0*4+3)*8 +: 8]),
|
||||||
.phy_4_tx_bad_block(),
|
.phy_4_tx_bad_block(),
|
||||||
.phy_4_rx_error_count(),
|
.phy_4_rx_error_count(),
|
||||||
.phy_4_rx_bad_block(),
|
.phy_4_rx_bad_block(),
|
||||||
@ -313,7 +302,11 @@ qsfp_phy_inst (
|
|||||||
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
||||||
);
|
);
|
||||||
|
|
||||||
fpga_core
|
fpga_core #(
|
||||||
|
.UART_CNT(UART_CNT),
|
||||||
|
.QSFP_CNT(QSFP_CNT),
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
core_inst (
|
core_inst (
|
||||||
/*
|
/*
|
||||||
* Clock: 156.25 MHz
|
* Clock: 156.25 MHz
|
||||||
@ -321,47 +314,33 @@ core_inst (
|
|||||||
*/
|
*/
|
||||||
.clk(clk_156mhz_int),
|
.clk(clk_156mhz_int),
|
||||||
.rst(rst_156mhz_int),
|
.rst(rst_156mhz_int),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
|
.sw(0),
|
||||||
|
.led(),
|
||||||
.qsfp_led_act(qsfp_led_act),
|
.qsfp_led_act(qsfp_led_act),
|
||||||
.qsfp_led_stat_g(qsfp_led_stat_g),
|
.qsfp_led_stat_g(qsfp_led_stat_g),
|
||||||
.qsfp_led_stat_y(qsfp_led_stat_y),
|
.qsfp_led_stat_y(qsfp_led_stat_y),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
.uart_txd(uart_txd),
|
||||||
|
.uart_rxd(uart_rxd),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
.qsfp_tx_clk_1(qsfp_tx_clk_1_int),
|
.eth_tx_clk(eth_tx_clk),
|
||||||
.qsfp_tx_rst_1(qsfp_tx_rst_1_int),
|
.eth_tx_rst(eth_tx_rst),
|
||||||
.qsfp_txd_1(qsfp_txd_1_int),
|
.eth_txd(eth_txd),
|
||||||
.qsfp_txc_1(qsfp_txc_1_int),
|
.eth_txc(eth_txc),
|
||||||
.qsfp_rx_clk_1(qsfp_rx_clk_1_int),
|
.eth_rx_clk(eth_rx_clk),
|
||||||
.qsfp_rx_rst_1(qsfp_rx_rst_1_int),
|
.eth_rx_rst(eth_rx_rst),
|
||||||
.qsfp_rxd_1(qsfp_rxd_1_int),
|
.eth_rxd(eth_rxd),
|
||||||
.qsfp_rxc_1(qsfp_rxc_1_int),
|
.eth_rxc(eth_rxc)
|
||||||
.qsfp_tx_clk_2(qsfp_tx_clk_2_int),
|
|
||||||
.qsfp_tx_rst_2(qsfp_tx_rst_2_int),
|
|
||||||
.qsfp_txd_2(qsfp_txd_2_int),
|
|
||||||
.qsfp_txc_2(qsfp_txc_2_int),
|
|
||||||
.qsfp_rx_clk_2(qsfp_rx_clk_2_int),
|
|
||||||
.qsfp_rx_rst_2(qsfp_rx_rst_2_int),
|
|
||||||
.qsfp_rxd_2(qsfp_rxd_2_int),
|
|
||||||
.qsfp_rxc_2(qsfp_rxc_2_int),
|
|
||||||
.qsfp_tx_clk_3(qsfp_tx_clk_3_int),
|
|
||||||
.qsfp_tx_rst_3(qsfp_tx_rst_3_int),
|
|
||||||
.qsfp_txd_3(qsfp_txd_3_int),
|
|
||||||
.qsfp_txc_3(qsfp_txc_3_int),
|
|
||||||
.qsfp_rx_clk_3(qsfp_rx_clk_3_int),
|
|
||||||
.qsfp_rx_rst_3(qsfp_rx_rst_3_int),
|
|
||||||
.qsfp_rxd_3(qsfp_rxd_3_int),
|
|
||||||
.qsfp_rxc_3(qsfp_rxc_3_int),
|
|
||||||
.qsfp_tx_clk_4(qsfp_tx_clk_4_int),
|
|
||||||
.qsfp_tx_rst_4(qsfp_tx_rst_4_int),
|
|
||||||
.qsfp_txd_4(qsfp_txd_4_int),
|
|
||||||
.qsfp_txc_4(qsfp_txc_4_int),
|
|
||||||
.qsfp_rx_clk_4(qsfp_rx_clk_4_int),
|
|
||||||
.qsfp_rx_rst_4(qsfp_rx_rst_4_int),
|
|
||||||
.qsfp_rxd_4(qsfp_rxd_4_int),
|
|
||||||
.qsfp_rxc_4(qsfp_rxc_4_int)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
474
fpga/lib/eth/example/Alveo/fpga_25g/rtl/fpga_au55.v
Normal file
474
fpga/lib/eth/example/Alveo/fpga_25g/rtl/fpga_au55.v
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2014-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 #
|
||||||
|
(
|
||||||
|
parameter QSFP_CNT = 2,
|
||||||
|
parameter UART_CNT = 3
|
||||||
|
)
|
||||||
|
(
|
||||||
|
/*
|
||||||
|
* Reset: Push button, active low
|
||||||
|
*/
|
||||||
|
input wire reset,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO
|
||||||
|
*/
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_act,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_g,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_y,
|
||||||
|
output wire hbm_cattrip,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
output wire [UART_CNT-1:0] uart_txd,
|
||||||
|
input wire [UART_CNT-1:0] uart_rxd,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ethernet: QSFP28
|
||||||
|
*/
|
||||||
|
output wire [3:0] qsfp0_tx_p,
|
||||||
|
output wire [3:0] qsfp0_tx_n,
|
||||||
|
input wire [3:0] qsfp0_rx_p,
|
||||||
|
input wire [3:0] qsfp0_rx_n,
|
||||||
|
input wire qsfp0_mgt_refclk_p,
|
||||||
|
input wire qsfp0_mgt_refclk_n,
|
||||||
|
|
||||||
|
output wire [3:0] qsfp1_tx_p,
|
||||||
|
output wire [3:0] qsfp1_tx_n,
|
||||||
|
input wire [3:0] qsfp1_rx_p,
|
||||||
|
input wire [3:0] qsfp1_rx_n,
|
||||||
|
input wire qsfp1_mgt_refclk_p,
|
||||||
|
input wire qsfp1_mgt_refclk_n
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clock and reset
|
||||||
|
|
||||||
|
wire clk_161mhz_ref_int;
|
||||||
|
|
||||||
|
// Internal 125 MHz clock
|
||||||
|
wire clk_125mhz_mmcm_out;
|
||||||
|
wire clk_125mhz_int;
|
||||||
|
wire rst_125mhz_int;
|
||||||
|
|
||||||
|
// Internal 156.25 MHz clock
|
||||||
|
wire clk_156mhz_int;
|
||||||
|
wire rst_156mhz_int;
|
||||||
|
|
||||||
|
wire mmcm_rst = 1'b0;
|
||||||
|
wire mmcm_locked;
|
||||||
|
wire mmcm_clkfb;
|
||||||
|
|
||||||
|
// MMCM instance
|
||||||
|
// 161.13 MHz in, 125 MHz out
|
||||||
|
// PFD range: 10 MHz to 500 MHz
|
||||||
|
// VCO range: 800 MHz to 1600 MHz
|
||||||
|
// M = 64, D = 11 sets Fvco = 937.5 MHz (in range)
|
||||||
|
// Divide by 7.5 to get output frequency of 125 MHz
|
||||||
|
MMCME4_BASE #(
|
||||||
|
.BANDWIDTH("OPTIMIZED"),
|
||||||
|
.CLKOUT0_DIVIDE_F(7.5),
|
||||||
|
.CLKOUT0_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT0_PHASE(0),
|
||||||
|
.CLKOUT1_DIVIDE(1),
|
||||||
|
.CLKOUT1_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT1_PHASE(0),
|
||||||
|
.CLKOUT2_DIVIDE(1),
|
||||||
|
.CLKOUT2_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT2_PHASE(0),
|
||||||
|
.CLKOUT3_DIVIDE(1),
|
||||||
|
.CLKOUT3_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT3_PHASE(0),
|
||||||
|
.CLKOUT4_DIVIDE(1),
|
||||||
|
.CLKOUT4_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT4_PHASE(0),
|
||||||
|
.CLKOUT5_DIVIDE(1),
|
||||||
|
.CLKOUT5_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT5_PHASE(0),
|
||||||
|
.CLKOUT6_DIVIDE(1),
|
||||||
|
.CLKOUT6_DUTY_CYCLE(0.5),
|
||||||
|
.CLKOUT6_PHASE(0),
|
||||||
|
.CLKFBOUT_MULT_F(64),
|
||||||
|
.CLKFBOUT_PHASE(0),
|
||||||
|
.DIVCLK_DIVIDE(11),
|
||||||
|
.REF_JITTER1(0.010),
|
||||||
|
.CLKIN1_PERIOD(6.206),
|
||||||
|
.STARTUP_WAIT("FALSE"),
|
||||||
|
.CLKOUT4_CASCADE("FALSE")
|
||||||
|
)
|
||||||
|
clk_mmcm_inst (
|
||||||
|
.CLKIN1(clk_161mhz_ref_int),
|
||||||
|
.CLKFBIN(mmcm_clkfb),
|
||||||
|
.RST(mmcm_rst),
|
||||||
|
.PWRDWN(1'b0),
|
||||||
|
.CLKOUT0(clk_125mhz_mmcm_out),
|
||||||
|
.CLKOUT0B(),
|
||||||
|
.CLKOUT1(),
|
||||||
|
.CLKOUT1B(),
|
||||||
|
.CLKOUT2(),
|
||||||
|
.CLKOUT2B(),
|
||||||
|
.CLKOUT3(),
|
||||||
|
.CLKOUT3B(),
|
||||||
|
.CLKOUT4(),
|
||||||
|
.CLKOUT5(),
|
||||||
|
.CLKOUT6(),
|
||||||
|
.CLKFBOUT(mmcm_clkfb),
|
||||||
|
.CLKFBOUTB(),
|
||||||
|
.LOCKED(mmcm_locked)
|
||||||
|
);
|
||||||
|
|
||||||
|
BUFG
|
||||||
|
clk_125mhz_bufg_inst (
|
||||||
|
.I(clk_125mhz_mmcm_out),
|
||||||
|
.O(clk_125mhz_int)
|
||||||
|
);
|
||||||
|
|
||||||
|
sync_reset #(
|
||||||
|
.N(4)
|
||||||
|
)
|
||||||
|
sync_reset_125mhz_inst (
|
||||||
|
.clk(clk_125mhz_int),
|
||||||
|
.rst(~mmcm_locked),
|
||||||
|
.out(rst_125mhz_int)
|
||||||
|
);
|
||||||
|
|
||||||
|
// GPIO
|
||||||
|
assign hbm_cattrip = 1'b0;
|
||||||
|
|
||||||
|
// XGMII 10G PHY
|
||||||
|
localparam CH_CNT = QSFP_CNT*4;
|
||||||
|
|
||||||
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_txc;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_rxd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_rxc;
|
||||||
|
|
||||||
|
assign clk_156mhz_int = eth_tx_clk[0];
|
||||||
|
assign rst_156mhz_int = eth_tx_rst[0];
|
||||||
|
|
||||||
|
// QSFP0
|
||||||
|
wire qsfp0_rx_block_lock_1;
|
||||||
|
wire qsfp0_rx_block_lock_2;
|
||||||
|
wire qsfp0_rx_block_lock_3;
|
||||||
|
wire qsfp0_rx_block_lock_4;
|
||||||
|
|
||||||
|
wire qsfp0_gtpowergood;
|
||||||
|
|
||||||
|
wire qsfp0_mgt_refclk;
|
||||||
|
wire qsfp0_mgt_refclk_int;
|
||||||
|
wire qsfp0_mgt_refclk_bufg;
|
||||||
|
|
||||||
|
assign clk_161mhz_ref_int = qsfp0_mgt_refclk_bufg;
|
||||||
|
|
||||||
|
IBUFDS_GTE4 ibufds_gte4_qsfp0_mgt_refclk_inst (
|
||||||
|
.I (qsfp0_mgt_refclk_p),
|
||||||
|
.IB (qsfp0_mgt_refclk_n),
|
||||||
|
.CEB (1'b0),
|
||||||
|
.O (qsfp0_mgt_refclk),
|
||||||
|
.ODIV2 (qsfp0_mgt_refclk_int)
|
||||||
|
);
|
||||||
|
|
||||||
|
BUFG_GT bufg_gt_refclk_inst (
|
||||||
|
.CE (qsfp0_gtpowergood),
|
||||||
|
.CEMASK (1'b1),
|
||||||
|
.CLR (1'b0),
|
||||||
|
.CLRMASK (1'b1),
|
||||||
|
.DIV (3'd0),
|
||||||
|
.I (qsfp0_mgt_refclk_int),
|
||||||
|
.O (qsfp0_mgt_refclk_bufg)
|
||||||
|
);
|
||||||
|
|
||||||
|
eth_xcvr_phy_quad_wrapper #(
|
||||||
|
.TX_SERDES_PIPELINE(2),
|
||||||
|
.RX_SERDES_PIPELINE(2),
|
||||||
|
.COUNT_125US(125000/2.56)
|
||||||
|
)
|
||||||
|
qsfp0_phy_inst (
|
||||||
|
.xcvr_ctrl_clk(clk_125mhz_int),
|
||||||
|
.xcvr_ctrl_rst(rst_125mhz_int),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common
|
||||||
|
*/
|
||||||
|
.xcvr_gtpowergood_out(qsfp0_gtpowergood),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PLL
|
||||||
|
*/
|
||||||
|
.xcvr_gtrefclk00_in(qsfp0_mgt_refclk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial data
|
||||||
|
*/
|
||||||
|
.xcvr_txp(qsfp0_tx_p),
|
||||||
|
.xcvr_txn(qsfp0_tx_n),
|
||||||
|
.xcvr_rxp(qsfp0_rx_p),
|
||||||
|
.xcvr_rxn(qsfp0_rx_n),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHY connections
|
||||||
|
*/
|
||||||
|
.phy_1_tx_clk(eth_tx_clk[0*4+0 +: 1]),
|
||||||
|
.phy_1_tx_rst(eth_tx_rst[0*4+0 +: 1]),
|
||||||
|
.phy_1_xgmii_txd(eth_txd[(0*4+0)*64 +: 64]),
|
||||||
|
.phy_1_xgmii_txc(eth_txc[(0*4+0)*8 +: 8]),
|
||||||
|
.phy_1_rx_clk(eth_rx_clk[0*4+0 +: 1]),
|
||||||
|
.phy_1_rx_rst(eth_rx_rst[0*4+0 +: 1]),
|
||||||
|
.phy_1_xgmii_rxd(eth_rxd[(0*4+0)*64 +: 64]),
|
||||||
|
.phy_1_xgmii_rxc(eth_rxc[(0*4+0)*8 +: 8]),
|
||||||
|
.phy_1_tx_bad_block(),
|
||||||
|
.phy_1_rx_error_count(),
|
||||||
|
.phy_1_rx_bad_block(),
|
||||||
|
.phy_1_rx_sequence_error(),
|
||||||
|
.phy_1_rx_block_lock(qsfp0_rx_block_lock_1),
|
||||||
|
.phy_1_rx_status(),
|
||||||
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_2_tx_clk(eth_tx_clk[0*4+1 +: 1]),
|
||||||
|
.phy_2_tx_rst(eth_tx_rst[0*4+1 +: 1]),
|
||||||
|
.phy_2_xgmii_txd(eth_txd[(0*4+1)*64 +: 64]),
|
||||||
|
.phy_2_xgmii_txc(eth_txc[(0*4+1)*8 +: 8]),
|
||||||
|
.phy_2_rx_clk(eth_rx_clk[0*4+1 +: 1]),
|
||||||
|
.phy_2_rx_rst(eth_rx_rst[0*4+1 +: 1]),
|
||||||
|
.phy_2_xgmii_rxd(eth_rxd[(0*4+1)*64 +: 64]),
|
||||||
|
.phy_2_xgmii_rxc(eth_rxc[(0*4+1)*8 +: 8]),
|
||||||
|
.phy_2_tx_bad_block(),
|
||||||
|
.phy_2_rx_error_count(),
|
||||||
|
.phy_2_rx_bad_block(),
|
||||||
|
.phy_2_rx_sequence_error(),
|
||||||
|
.phy_2_rx_block_lock(qsfp0_rx_block_lock_2),
|
||||||
|
.phy_2_rx_status(),
|
||||||
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_3_tx_clk(eth_tx_clk[0*4+2 +: 1]),
|
||||||
|
.phy_3_tx_rst(eth_tx_rst[0*4+2 +: 1]),
|
||||||
|
.phy_3_xgmii_txd(eth_txd[(0*4+2)*64 +: 64]),
|
||||||
|
.phy_3_xgmii_txc(eth_txc[(0*4+2)*8 +: 8]),
|
||||||
|
.phy_3_rx_clk(eth_rx_clk[0*4+2 +: 1]),
|
||||||
|
.phy_3_rx_rst(eth_rx_rst[0*4+2 +: 1]),
|
||||||
|
.phy_3_xgmii_rxd(eth_rxd[(0*4+2)*64 +: 64]),
|
||||||
|
.phy_3_xgmii_rxc(eth_rxc[(0*4+2)*8 +: 8]),
|
||||||
|
.phy_3_tx_bad_block(),
|
||||||
|
.phy_3_rx_error_count(),
|
||||||
|
.phy_3_rx_bad_block(),
|
||||||
|
.phy_3_rx_sequence_error(),
|
||||||
|
.phy_3_rx_block_lock(qsfp0_rx_block_lock_3),
|
||||||
|
.phy_3_rx_status(),
|
||||||
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_4_tx_clk(eth_tx_clk[0*4+3 +: 1]),
|
||||||
|
.phy_4_tx_rst(eth_tx_rst[0*4+3 +: 1]),
|
||||||
|
.phy_4_xgmii_txd(eth_txd[(0*4+3)*64 +: 64]),
|
||||||
|
.phy_4_xgmii_txc(eth_txc[(0*4+3)*8 +: 8]),
|
||||||
|
.phy_4_rx_clk(eth_rx_clk[0*4+3 +: 1]),
|
||||||
|
.phy_4_rx_rst(eth_rx_rst[0*4+3 +: 1]),
|
||||||
|
.phy_4_xgmii_rxd(eth_rxd[(0*4+3)*64 +: 64]),
|
||||||
|
.phy_4_xgmii_rxc(eth_rxc[(0*4+3)*8 +: 8]),
|
||||||
|
.phy_4_tx_bad_block(),
|
||||||
|
.phy_4_rx_error_count(),
|
||||||
|
.phy_4_rx_bad_block(),
|
||||||
|
.phy_4_rx_sequence_error(),
|
||||||
|
.phy_4_rx_block_lock(qsfp0_rx_block_lock_4),
|
||||||
|
.phy_4_rx_status(),
|
||||||
|
.phy_4_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// QSFP1
|
||||||
|
wire qsfp1_rx_block_lock_1;
|
||||||
|
wire qsfp1_rx_block_lock_2;
|
||||||
|
wire qsfp1_rx_block_lock_3;
|
||||||
|
wire qsfp1_rx_block_lock_4;
|
||||||
|
|
||||||
|
wire qsfp1_mgt_refclk;
|
||||||
|
|
||||||
|
IBUFDS_GTE4 ibufds_gte4_qsfp1_mgt_refclk_inst (
|
||||||
|
.I (qsfp1_mgt_refclk_p),
|
||||||
|
.IB (qsfp1_mgt_refclk_n),
|
||||||
|
.CEB (1'b0),
|
||||||
|
.O (qsfp1_mgt_refclk),
|
||||||
|
.ODIV2 ()
|
||||||
|
);
|
||||||
|
|
||||||
|
eth_xcvr_phy_quad_wrapper #(
|
||||||
|
.TX_SERDES_PIPELINE(2),
|
||||||
|
.RX_SERDES_PIPELINE(2),
|
||||||
|
.COUNT_125US(125000/2.56)
|
||||||
|
)
|
||||||
|
qsfp1_phy_inst (
|
||||||
|
.xcvr_ctrl_clk(clk_125mhz_int),
|
||||||
|
.xcvr_ctrl_rst(rst_125mhz_int),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common
|
||||||
|
*/
|
||||||
|
.xcvr_gtpowergood_out(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PLL
|
||||||
|
*/
|
||||||
|
.xcvr_gtrefclk00_in(qsfp1_mgt_refclk),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial data
|
||||||
|
*/
|
||||||
|
.xcvr_txp(qsfp1_tx_p),
|
||||||
|
.xcvr_txn(qsfp1_tx_n),
|
||||||
|
.xcvr_rxp(qsfp1_rx_p),
|
||||||
|
.xcvr_rxn(qsfp1_rx_n),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHY connections
|
||||||
|
*/
|
||||||
|
.phy_1_tx_clk(eth_tx_clk[1*4+0 +: 1]),
|
||||||
|
.phy_1_tx_rst(eth_tx_rst[1*4+0 +: 1]),
|
||||||
|
.phy_1_xgmii_txd(eth_txd[(1*4+0)*64 +: 64]),
|
||||||
|
.phy_1_xgmii_txc(eth_txc[(1*4+0)*8 +: 8]),
|
||||||
|
.phy_1_rx_clk(eth_rx_clk[1*4+0 +: 1]),
|
||||||
|
.phy_1_rx_rst(eth_rx_rst[1*4+0 +: 1]),
|
||||||
|
.phy_1_xgmii_rxd(eth_rxd[(1*4+0)*64 +: 64]),
|
||||||
|
.phy_1_xgmii_rxc(eth_rxc[(1*4+0)*8 +: 8]),
|
||||||
|
.phy_1_tx_bad_block(),
|
||||||
|
.phy_1_rx_error_count(),
|
||||||
|
.phy_1_rx_bad_block(),
|
||||||
|
.phy_1_rx_sequence_error(),
|
||||||
|
.phy_1_rx_block_lock(qsfp1_rx_block_lock_1),
|
||||||
|
.phy_1_rx_status(),
|
||||||
|
.phy_1_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_1_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_2_tx_clk(eth_tx_clk[1*4+1 +: 1]),
|
||||||
|
.phy_2_tx_rst(eth_tx_rst[1*4+1 +: 1]),
|
||||||
|
.phy_2_xgmii_txd(eth_txd[(1*4+1)*64 +: 64]),
|
||||||
|
.phy_2_xgmii_txc(eth_txc[(1*4+1)*8 +: 8]),
|
||||||
|
.phy_2_rx_clk(eth_rx_clk[1*4+1 +: 1]),
|
||||||
|
.phy_2_rx_rst(eth_rx_rst[1*4+1 +: 1]),
|
||||||
|
.phy_2_xgmii_rxd(eth_rxd[(1*4+1)*64 +: 64]),
|
||||||
|
.phy_2_xgmii_rxc(eth_rxc[(1*4+1)*8 +: 8]),
|
||||||
|
.phy_2_tx_bad_block(),
|
||||||
|
.phy_2_rx_error_count(),
|
||||||
|
.phy_2_rx_bad_block(),
|
||||||
|
.phy_2_rx_sequence_error(),
|
||||||
|
.phy_2_rx_block_lock(qsfp1_rx_block_lock_2),
|
||||||
|
.phy_2_rx_status(),
|
||||||
|
.phy_2_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_2_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_3_tx_clk(eth_tx_clk[1*4+2 +: 1]),
|
||||||
|
.phy_3_tx_rst(eth_tx_rst[1*4+2 +: 1]),
|
||||||
|
.phy_3_xgmii_txd(eth_txd[(1*4+2)*64 +: 64]),
|
||||||
|
.phy_3_xgmii_txc(eth_txc[(1*4+2)*8 +: 8]),
|
||||||
|
.phy_3_rx_clk(eth_rx_clk[1*4+2 +: 1]),
|
||||||
|
.phy_3_rx_rst(eth_rx_rst[1*4+2 +: 1]),
|
||||||
|
.phy_3_xgmii_rxd(eth_rxd[(1*4+2)*64 +: 64]),
|
||||||
|
.phy_3_xgmii_rxc(eth_rxc[(1*4+2)*8 +: 8]),
|
||||||
|
.phy_3_tx_bad_block(),
|
||||||
|
.phy_3_rx_error_count(),
|
||||||
|
.phy_3_rx_bad_block(),
|
||||||
|
.phy_3_rx_sequence_error(),
|
||||||
|
.phy_3_rx_block_lock(qsfp1_rx_block_lock_3),
|
||||||
|
.phy_3_rx_status(),
|
||||||
|
.phy_3_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_3_cfg_rx_prbs31_enable(1'b0),
|
||||||
|
|
||||||
|
.phy_4_tx_clk(eth_tx_clk[1*4+3 +: 1]),
|
||||||
|
.phy_4_tx_rst(eth_tx_rst[1*4+3 +: 1]),
|
||||||
|
.phy_4_xgmii_txd(eth_txd[(1*4+3)*64 +: 64]),
|
||||||
|
.phy_4_xgmii_txc(eth_txc[(1*4+3)*8 +: 8]),
|
||||||
|
.phy_4_rx_clk(eth_rx_clk[1*4+3 +: 1]),
|
||||||
|
.phy_4_rx_rst(eth_rx_rst[1*4+3 +: 1]),
|
||||||
|
.phy_4_xgmii_rxd(eth_rxd[(1*4+3)*64 +: 64]),
|
||||||
|
.phy_4_xgmii_rxc(eth_rxc[(1*4+3)*8 +: 8]),
|
||||||
|
.phy_4_tx_bad_block(),
|
||||||
|
.phy_4_rx_error_count(),
|
||||||
|
.phy_4_rx_bad_block(),
|
||||||
|
.phy_4_rx_sequence_error(),
|
||||||
|
.phy_4_rx_block_lock(qsfp1_rx_block_lock_4),
|
||||||
|
.phy_4_rx_status(),
|
||||||
|
.phy_4_cfg_tx_prbs31_enable(1'b0),
|
||||||
|
.phy_4_cfg_rx_prbs31_enable(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
fpga_core #(
|
||||||
|
.UART_CNT(UART_CNT),
|
||||||
|
.QSFP_CNT(QSFP_CNT),
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
|
core_inst (
|
||||||
|
/*
|
||||||
|
* Clock: 156.25 MHz
|
||||||
|
* Synchronous reset
|
||||||
|
*/
|
||||||
|
.clk(clk_156mhz_int),
|
||||||
|
.rst(rst_156mhz_int),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO
|
||||||
|
*/
|
||||||
|
.sw(0),
|
||||||
|
.led(),
|
||||||
|
.qsfp_led_act(qsfp_led_act),
|
||||||
|
.qsfp_led_stat_g(qsfp_led_stat_g),
|
||||||
|
.qsfp_led_stat_y(qsfp_led_stat_y),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
.uart_txd(uart_txd),
|
||||||
|
.uart_rxd(uart_rxd),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ethernet: QSFP28
|
||||||
|
*/
|
||||||
|
.eth_tx_clk(eth_tx_clk),
|
||||||
|
.eth_tx_rst(eth_tx_rst),
|
||||||
|
.eth_txd(eth_txd),
|
||||||
|
.eth_txc(eth_txc),
|
||||||
|
.eth_rx_clk(eth_rx_clk),
|
||||||
|
.eth_rx_rst(eth_rx_rst),
|
||||||
|
.eth_rxd(eth_rxd),
|
||||||
|
.eth_rxc(eth_rxc)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
@ -33,7 +33,11 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
module fpga_core #
|
module fpga_core #
|
||||||
(
|
(
|
||||||
parameter TARGET = "XILINX"
|
parameter SW_CNT = 4,
|
||||||
|
parameter LED_CNT = 3,
|
||||||
|
parameter UART_CNT = 1,
|
||||||
|
parameter QSFP_CNT = 2,
|
||||||
|
parameter CH_CNT = QSFP_CNT*4
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
/*
|
/*
|
||||||
@ -42,48 +46,33 @@ module fpga_core #
|
|||||||
*/
|
*/
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
output wire qsfp_led_act,
|
input wire [SW_CNT-1:0] sw,
|
||||||
output wire qsfp_led_stat_g,
|
output wire [LED_CNT-1:0] led,
|
||||||
output wire qsfp_led_stat_y,
|
output wire [QSFP_CNT-1:0] qsfp_led_act,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_g,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_y,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* UART
|
||||||
*/
|
*/
|
||||||
input wire qsfp_tx_clk_1,
|
output wire [UART_CNT-1:0] uart_txd,
|
||||||
input wire qsfp_tx_rst_1,
|
input wire [UART_CNT-1:0] uart_rxd,
|
||||||
output wire [63:0] qsfp_txd_1,
|
|
||||||
output wire [7:0] qsfp_txc_1,
|
/*
|
||||||
input wire qsfp_rx_clk_1,
|
* Ethernet
|
||||||
input wire qsfp_rx_rst_1,
|
*/
|
||||||
input wire [63:0] qsfp_rxd_1,
|
input wire [CH_CNT-1:0] eth_tx_clk,
|
||||||
input wire [7:0] qsfp_rxc_1,
|
input wire [CH_CNT-1:0] eth_tx_rst,
|
||||||
input wire qsfp_tx_clk_2,
|
output wire [CH_CNT*64-1:0] eth_txd,
|
||||||
input wire qsfp_tx_rst_2,
|
output wire [CH_CNT*8-1:0] eth_txc,
|
||||||
output wire [63:0] qsfp_txd_2,
|
input wire [CH_CNT-1:0] eth_rx_clk,
|
||||||
output wire [7:0] qsfp_txc_2,
|
input wire [CH_CNT-1:0] eth_rx_rst,
|
||||||
input wire qsfp_rx_clk_2,
|
input wire [CH_CNT*64-1:0] eth_rxd,
|
||||||
input wire qsfp_rx_rst_2,
|
input wire [CH_CNT*8-1:0] eth_rxc
|
||||||
input wire [63:0] qsfp_rxd_2,
|
|
||||||
input wire [7:0] qsfp_rxc_2,
|
|
||||||
input wire qsfp_tx_clk_3,
|
|
||||||
input wire qsfp_tx_rst_3,
|
|
||||||
output wire [63:0] qsfp_txd_3,
|
|
||||||
output wire [7:0] qsfp_txc_3,
|
|
||||||
input wire qsfp_rx_clk_3,
|
|
||||||
input wire qsfp_rx_rst_3,
|
|
||||||
input wire [63:0] qsfp_rxd_3,
|
|
||||||
input wire [7:0] qsfp_rxc_3,
|
|
||||||
input wire qsfp_tx_clk_4,
|
|
||||||
input wire qsfp_tx_rst_4,
|
|
||||||
output wire [63:0] qsfp_txd_4,
|
|
||||||
output wire [7:0] qsfp_txc_4,
|
|
||||||
input wire qsfp_rx_clk_4,
|
|
||||||
input wire qsfp_rx_rst_4,
|
|
||||||
input wire [63:0] qsfp_rxd_4,
|
|
||||||
input wire [7:0] qsfp_rxc_4
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// AXI between MAC and Ethernet modules
|
// AXI between MAC and Ethernet modules
|
||||||
@ -320,14 +309,21 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign qsfp_led_act = led_reg[0];
|
//assign led = sw;
|
||||||
|
assign led = led_reg;
|
||||||
|
|
||||||
assign qsfp_txd_2 = 64'h0707070707070707;
|
assign uart_txd = uart_rxd;
|
||||||
assign qsfp_txc_2 = 8'hff;
|
|
||||||
assign qsfp_txd_3 = 64'h0707070707070707;
|
generate
|
||||||
assign qsfp_txc_3 = 8'hff;
|
|
||||||
assign qsfp_txd_4 = 64'h0707070707070707;
|
genvar n;
|
||||||
assign qsfp_txc_4 = 8'hff;
|
|
||||||
|
for (n = 1; n < CH_CNT; n = n + 1) begin
|
||||||
|
assign eth_txd[n*64 +: 64] = 64'h0707070707070707;
|
||||||
|
assign eth_txc[n*8 +: 8] = 8'hff;
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
eth_mac_10g_fifo #(
|
eth_mac_10g_fifo #(
|
||||||
.ENABLE_PADDING(1),
|
.ENABLE_PADDING(1),
|
||||||
@ -339,10 +335,10 @@ eth_mac_10g_fifo #(
|
|||||||
.RX_FRAME_FIFO(1)
|
.RX_FRAME_FIFO(1)
|
||||||
)
|
)
|
||||||
eth_mac_10g_fifo_inst (
|
eth_mac_10g_fifo_inst (
|
||||||
.rx_clk(qsfp_rx_clk_1),
|
.rx_clk(eth_rx_clk[0 +: 1]),
|
||||||
.rx_rst(qsfp_rx_rst_1),
|
.rx_rst(eth_rx_rst[0 +: 1]),
|
||||||
.tx_clk(qsfp_tx_clk_1),
|
.tx_clk(eth_tx_clk[0 +: 1]),
|
||||||
.tx_rst(qsfp_tx_rst_1),
|
.tx_rst(eth_tx_rst[0 +: 1]),
|
||||||
.logic_clk(clk),
|
.logic_clk(clk),
|
||||||
.logic_rst(rst),
|
.logic_rst(rst),
|
||||||
|
|
||||||
@ -360,10 +356,10 @@ eth_mac_10g_fifo_inst (
|
|||||||
.rx_axis_tlast(rx_axis_tlast),
|
.rx_axis_tlast(rx_axis_tlast),
|
||||||
.rx_axis_tuser(rx_axis_tuser),
|
.rx_axis_tuser(rx_axis_tuser),
|
||||||
|
|
||||||
.xgmii_rxd(qsfp_rxd_1),
|
.xgmii_rxd(eth_rxd[0*64 +: 64]),
|
||||||
.xgmii_rxc(qsfp_rxc_1),
|
.xgmii_rxc(eth_rxc[0*8 +: 8]),
|
||||||
.xgmii_txd(qsfp_txd_1),
|
.xgmii_txd(eth_txd[0*64 +: 64]),
|
||||||
.xgmii_txc(qsfp_txc_1),
|
.xgmii_txc(eth_txc[0*8 +: 8]),
|
||||||
|
|
||||||
.tx_fifo_overflow(),
|
.tx_fifo_overflow(),
|
||||||
.tx_fifo_bad_frame(),
|
.tx_fifo_bad_frame(),
|
@ -27,8 +27,9 @@ COCOTB_HDL_TIMEUNIT = 1ns
|
|||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||||
|
|
||||||
DUT = fpga_core
|
DUT = fpga_core
|
||||||
TOPLEVEL = $(DUT)
|
TOPLEVEL = test_$(DUT)
|
||||||
MODULE = test_$(DUT)
|
MODULE = test_$(DUT)
|
||||||
|
VERILOG_SOURCES += $(TOPLEVEL).v
|
||||||
VERILOG_SOURCES += ../../rtl/$(DUT).v
|
VERILOG_SOURCES += ../../rtl/$(DUT).v
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v
|
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v
|
||||||
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v
|
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v
|
||||||
@ -59,12 +60,16 @@ VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
|
|||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
|
||||||
# module parameters
|
# module parameters
|
||||||
#export PARAM_A := value
|
export PARAM_SW_CNT := 4
|
||||||
|
export PARAM_LED_CNT := 3
|
||||||
|
export PARAM_UART_CNT := 1
|
||||||
|
export PARAM_QSFP_CNT := 2
|
||||||
|
export PARAM_CH_CNT := $(shell expr $(PARAM_QSFP_CNT) \* 4)
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
ifeq ($(SIM), icarus)
|
||||||
PLUSARGS += -fst
|
PLUSARGS += -fst
|
||||||
|
|
||||||
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
|
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
VERILOG_SOURCES += iverilog_dump.v
|
VERILOG_SOURCES += iverilog_dump.v
|
||||||
@ -73,7 +78,7 @@ ifeq ($(SIM), icarus)
|
|||||||
else ifeq ($(SIM), verilator)
|
else ifeq ($(SIM), verilator)
|
||||||
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
||||||
|
|
||||||
# COMPILE_ARGS += -GA=$(PARAM_A)
|
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
COMPILE_ARGS += --trace-fst
|
COMPILE_ARGS += --trace-fst
|
@ -48,39 +48,39 @@ class TB:
|
|||||||
cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start())
|
cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start())
|
||||||
|
|
||||||
# Ethernet
|
# Ethernet
|
||||||
self.qsfp_source = []
|
self.ch_source = []
|
||||||
self.qsfp_sink = []
|
self.ch_sink = []
|
||||||
|
|
||||||
for y in range(1, 5):
|
for ch in self.dut.ch:
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp_rx_clk_{y}"), 2.56, units="ns").start())
|
cocotb.start_soon(Clock(ch.ch_rx_clk, 2.56, units="ns").start())
|
||||||
source = XgmiiSource(getattr(dut, f"qsfp_rxd_{y}"), getattr(dut, f"qsfp_rxc_{y}"), getattr(dut, f"qsfp_rx_clk_{y}"), getattr(dut, f"qsfp_rx_rst_{y}"))
|
source = XgmiiSource(ch.ch_rxd, ch.ch_rxc, ch.ch_rx_clk, ch.ch_rx_rst)
|
||||||
self.qsfp_source.append(source)
|
self.ch_source.append(source)
|
||||||
cocotb.start_soon(Clock(getattr(dut, f"qsfp_tx_clk_{y}"), 2.56, units="ns").start())
|
cocotb.start_soon(Clock(ch.ch_tx_clk, 2.56, units="ns").start())
|
||||||
sink = XgmiiSink(getattr(dut, f"qsfp_txd_{y}"), getattr(dut, f"qsfp_txc_{y}"), getattr(dut, f"qsfp_tx_clk_{y}"), getattr(dut, f"qsfp_tx_rst_{y}"))
|
sink = XgmiiSink(ch.ch_txd, ch.ch_txc, ch.ch_tx_clk, ch.ch_tx_rst)
|
||||||
self.qsfp_sink.append(sink)
|
self.ch_sink.append(sink)
|
||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
|
|
||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
for y in range(1, 5):
|
for ch in self.dut.ch:
|
||||||
getattr(self.dut, f"qsfp_rx_rst_{y}").setimmediatevalue(0)
|
ch.ch_rx_rst.setimmediatevalue(0)
|
||||||
getattr(self.dut, f"qsfp_tx_rst_{y}").setimmediatevalue(0)
|
ch.ch_tx_rst.setimmediatevalue(0)
|
||||||
|
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
self.dut.rst.value = 1
|
self.dut.rst.value = 1
|
||||||
for y in range(1, 5):
|
for ch in self.dut.ch:
|
||||||
getattr(self.dut, f"qsfp_rx_rst_{y}").value = 1
|
ch.ch_rx_rst.value = 1
|
||||||
getattr(self.dut, f"qsfp_tx_rst_{y}").value = 1
|
ch.ch_tx_rst.value = 1
|
||||||
|
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
self.dut.rst.value = 0
|
self.dut.rst.value = 0
|
||||||
for y in range(1, 5):
|
for ch in self.dut.ch:
|
||||||
getattr(self.dut, f"qsfp_rx_rst_{y}").value = 0
|
ch.ch_rx_rst.value = 0
|
||||||
getattr(self.dut, f"qsfp_tx_rst_{y}").value = 0
|
ch.ch_tx_rst.value = 0
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
@cocotb.test()
|
||||||
@ -100,11 +100,11 @@ async def run_test(dut):
|
|||||||
|
|
||||||
test_frame = XgmiiFrame.from_payload(test_pkt.build())
|
test_frame = XgmiiFrame.from_payload(test_pkt.build())
|
||||||
|
|
||||||
await tb.qsfp_source[0].send(test_frame)
|
await tb.ch_source[0].send(test_frame)
|
||||||
|
|
||||||
tb.log.info("receive ARP request")
|
tb.log.info("receive ARP request")
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0].recv()
|
rx_frame = await tb.ch_sink[0].recv()
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
||||||
|
|
||||||
@ -132,11 +132,11 @@ async def run_test(dut):
|
|||||||
|
|
||||||
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
|
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
|
||||||
|
|
||||||
await tb.qsfp_source[0].send(resp_frame)
|
await tb.ch_source[0].send(resp_frame)
|
||||||
|
|
||||||
tb.log.info("receive UDP packet")
|
tb.log.info("receive UDP packet")
|
||||||
|
|
||||||
rx_frame = await tb.qsfp_sink[0].recv()
|
rx_frame = await tb.ch_sink[0].recv()
|
||||||
|
|
||||||
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
rx_pkt = Ether(bytes(rx_frame.get_payload()))
|
||||||
|
|
||||||
@ -166,9 +166,10 @@ eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl'))
|
|||||||
def test_fpga_core(request):
|
def test_fpga_core(request):
|
||||||
dut = "fpga_core"
|
dut = "fpga_core"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
toplevel = dut
|
toplevel = "test_fpga_core"
|
||||||
|
|
||||||
verilog_sources = [
|
verilog_sources = [
|
||||||
|
os.path.join(tests_dir, f"{toplevel}.v"),
|
||||||
os.path.join(rtl_dir, f"{dut}.v"),
|
os.path.join(rtl_dir, f"{dut}.v"),
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"),
|
os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"),
|
||||||
os.path.join(eth_rtl_dir, "eth_mac_10g.v"),
|
os.path.join(eth_rtl_dir, "eth_mac_10g.v"),
|
||||||
@ -201,7 +202,11 @@ def test_fpga_core(request):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
# parameters['A'] = val
|
parameters['SW_CNT'] = 4
|
||||||
|
parameters['LED_CNT'] = 3
|
||||||
|
parameters['UART_CNT'] = 1
|
||||||
|
parameters['QSFP_CNT'] = 2
|
||||||
|
parameters['CH_CNT'] = parameters['QSFP_CNT']*4
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2023 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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Testbench top-level module
|
||||||
|
*/
|
||||||
|
module test_fpga_core #
|
||||||
|
(
|
||||||
|
parameter SW_CNT = 4,
|
||||||
|
parameter LED_CNT = 3,
|
||||||
|
parameter UART_CNT = 1,
|
||||||
|
parameter QSFP_CNT = 2,
|
||||||
|
parameter CH_CNT = QSFP_CNT*4
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire clk,
|
||||||
|
input wire rst,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO
|
||||||
|
*/
|
||||||
|
input wire [SW_CNT-1:0] sw,
|
||||||
|
output wire [LED_CNT-1:0] led,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_act,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_g,
|
||||||
|
output wire [QSFP_CNT-1:0] qsfp_led_stat_y,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
output wire [UART_CNT-1:0] uart_txd,
|
||||||
|
input wire [UART_CNT-1:0] uart_rxd
|
||||||
|
);
|
||||||
|
|
||||||
|
genvar n;
|
||||||
|
|
||||||
|
// XGMII 10G PHY
|
||||||
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_txc;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_clk;
|
||||||
|
wire [CH_CNT-1:0] eth_rx_rst;
|
||||||
|
wire [CH_CNT*64-1:0] eth_rxd;
|
||||||
|
wire [CH_CNT*8-1:0] eth_rxc;
|
||||||
|
|
||||||
|
generate
|
||||||
|
|
||||||
|
for (n = 0; n < CH_CNT; n = n + 1) begin : ch
|
||||||
|
|
||||||
|
wire ch_tx_clk;
|
||||||
|
wire ch_tx_rst;
|
||||||
|
wire [63:0] ch_txd;
|
||||||
|
wire [7:0] ch_txc;
|
||||||
|
wire ch_rx_clk;
|
||||||
|
wire ch_rx_rst;
|
||||||
|
wire [63:0] ch_rxd;
|
||||||
|
wire [7:0] ch_rxc;
|
||||||
|
|
||||||
|
assign eth_tx_clk[n +: 1] = ch_tx_clk;
|
||||||
|
assign eth_tx_rst[n +: 1] = ch_tx_rst;
|
||||||
|
assign ch_txd = eth_txd[n*64 +: 64];
|
||||||
|
assign ch_txc = eth_txc[n*8 +: 8];
|
||||||
|
assign eth_rx_clk[n +: 1] = ch_rx_clk;
|
||||||
|
assign eth_rx_rst[n +: 1] = ch_rx_rst;
|
||||||
|
assign eth_rxd[n*64 +: 64] = ch_rxd;
|
||||||
|
assign eth_rxc[n*8 +: 8] = ch_rxc;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
fpga_core #(
|
||||||
|
.SW_CNT(SW_CNT),
|
||||||
|
.LED_CNT(LED_CNT),
|
||||||
|
.UART_CNT(UART_CNT),
|
||||||
|
.QSFP_CNT(QSFP_CNT),
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
|
core_inst (
|
||||||
|
/*
|
||||||
|
* Clock: 156.25 MHz
|
||||||
|
* Synchronous reset
|
||||||
|
*/
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO
|
||||||
|
*/
|
||||||
|
.sw(sw),
|
||||||
|
.led(led),
|
||||||
|
.qsfp_led_act(qsfp_led_act),
|
||||||
|
.qsfp_led_stat_g(qsfp_led_stat_g),
|
||||||
|
.qsfp_led_stat_y(qsfp_led_stat_y),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART
|
||||||
|
*/
|
||||||
|
.uart_txd(uart_txd),
|
||||||
|
.uart_rxd(uart_rxd),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ethernet: QSFP28
|
||||||
|
*/
|
||||||
|
.eth_tx_clk(eth_tx_clk),
|
||||||
|
.eth_tx_rst(eth_tx_rst),
|
||||||
|
.eth_txd(eth_txd),
|
||||||
|
.eth_txc(eth_txc),
|
||||||
|
.eth_rx_clk(eth_rx_clk),
|
||||||
|
.eth_rx_rst(eth_rx_rst),
|
||||||
|
.eth_rxd(eth_rxd),
|
||||||
|
.eth_rxc(eth_rxc)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`resetall
|
@ -31,7 +31,12 @@ THE SOFTWARE.
|
|||||||
/*
|
/*
|
||||||
* FPGA top-level module
|
* FPGA top-level module
|
||||||
*/
|
*/
|
||||||
module fpga (
|
module fpga #
|
||||||
|
(
|
||||||
|
parameter QUAD_CNT = 17,
|
||||||
|
parameter CH_CNT = QUAD_CNT*4
|
||||||
|
)
|
||||||
|
(
|
||||||
/*
|
/*
|
||||||
* Clock: 156.25MHz
|
* Clock: 156.25MHz
|
||||||
*/
|
*/
|
||||||
@ -41,12 +46,12 @@ module fpga (
|
|||||||
/*
|
/*
|
||||||
* Ethernet: QSFP28
|
* Ethernet: QSFP28
|
||||||
*/
|
*/
|
||||||
input wire [67:0] eth_gt_ch_rx_p,
|
input wire [CH_CNT-1:0] eth_gt_ch_rx_p,
|
||||||
input wire [67:0] eth_gt_ch_rx_n,
|
input wire [CH_CNT-1:0] eth_gt_ch_rx_n,
|
||||||
output wire [67:0] eth_gt_ch_tx_p,
|
output wire [CH_CNT-1:0] eth_gt_ch_tx_p,
|
||||||
output wire [67:0] eth_gt_ch_tx_n,
|
output wire [CH_CNT-1:0] eth_gt_ch_tx_n,
|
||||||
input wire [16:0] eth_gt_pri_refclk_p,
|
input wire [QUAD_CNT-1:0] eth_gt_pri_refclk_p,
|
||||||
input wire [16:0] eth_gt_pri_refclk_n
|
input wire [QUAD_CNT-1:0] eth_gt_pri_refclk_n
|
||||||
);
|
);
|
||||||
|
|
||||||
genvar n;
|
genvar n;
|
||||||
@ -161,9 +166,6 @@ sync_reset_125mhz_inst (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// XGMII 10G PHY
|
// XGMII 10G PHY
|
||||||
parameter QUAD_CNT = 17;
|
|
||||||
parameter CH_CNT = QUAD_CNT*4;
|
|
||||||
|
|
||||||
wire [CH_CNT-1:0] eth_tx_clk;
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
wire [CH_CNT-1:0] eth_tx_rst;
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
wire [CH_CNT*64-1:0] eth_txd;
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
|
@ -290,160 +290,16 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign eth_txd[1*64 +: 64] = 64'h0707070707070707;
|
generate
|
||||||
assign eth_txc[1*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[2*64 +: 64] = 64'h0707070707070707;
|
genvar n;
|
||||||
assign eth_txc[2*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[3*64 +: 64] = 64'h0707070707070707;
|
for (n = 1; n < CH_CNT; n = n + 1) begin
|
||||||
assign eth_txc[3*8 +: 8] = 8'hff;
|
assign eth_txd[n*64 +: 64] = 64'h0707070707070707;
|
||||||
assign eth_txd[4*64 +: 64] = 64'h0707070707070707;
|
assign eth_txc[n*8 +: 8] = 8'hff;
|
||||||
assign eth_txc[4*8 +: 8] = 8'hff;
|
end
|
||||||
assign eth_txd[5*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[5*8 +: 8] = 8'hff;
|
endgenerate
|
||||||
assign eth_txd[6*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[6*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[7*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[7*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[8*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[8*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[9*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[9*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[10*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[10*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[11*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[11*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[12*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[12*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[13*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[13*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[14*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[14*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[15*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[15*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[16*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[16*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[17*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[17*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[18*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[18*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[19*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[19*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[10*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[10*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[11*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[11*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[12*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[12*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[13*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[13*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[14*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[14*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[15*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[15*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[16*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[16*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[17*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[17*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[18*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[18*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[19*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[19*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[20*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[20*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[21*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[21*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[22*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[22*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[23*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[23*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[24*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[24*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[25*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[25*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[26*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[26*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[27*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[27*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[28*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[28*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[29*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[29*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[30*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[30*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[31*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[31*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[32*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[32*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[33*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[33*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[34*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[34*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[35*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[35*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[36*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[36*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[37*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[37*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[38*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[38*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[39*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[39*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[40*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[40*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[41*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[41*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[42*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[42*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[43*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[43*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[44*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[44*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[45*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[45*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[46*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[46*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[47*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[47*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[48*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[48*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[49*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[49*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[50*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[50*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[51*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[51*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[52*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[52*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[53*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[53*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[54*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[54*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[55*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[55*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[56*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[56*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[57*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[57*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[58*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[58*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[59*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[59*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[60*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[60*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[61*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[61*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[62*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[62*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[63*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[63*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[64*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[64*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[65*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[65*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[66*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[66*8 +: 8] = 8'hff;
|
|
||||||
assign eth_txd[67*64 +: 64] = 64'h0707070707070707;
|
|
||||||
assign eth_txc[67*8 +: 8] = 8'hff;
|
|
||||||
|
|
||||||
eth_mac_10g_fifo #(
|
eth_mac_10g_fifo #(
|
||||||
.ENABLE_PADDING(1),
|
.ENABLE_PADDING(1),
|
||||||
|
@ -60,12 +60,13 @@ VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
|
|||||||
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||||
|
|
||||||
# module parameters
|
# module parameters
|
||||||
#export PARAM_A := value
|
export PARAM_QUAD_CNT := 17
|
||||||
|
export PARAM_CH_CNT := $(shell expr $(PARAM_QUAD_CNT) \* 4)
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
ifeq ($(SIM), icarus)
|
||||||
PLUSARGS += -fst
|
PLUSARGS += -fst
|
||||||
|
|
||||||
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
|
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
VERILOG_SOURCES += iverilog_dump.v
|
VERILOG_SOURCES += iverilog_dump.v
|
||||||
@ -74,7 +75,7 @@ ifeq ($(SIM), icarus)
|
|||||||
else ifeq ($(SIM), verilator)
|
else ifeq ($(SIM), verilator)
|
||||||
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
||||||
|
|
||||||
# COMPILE_ARGS += -GA=$(PARAM_A)
|
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
COMPILE_ARGS += --trace-fst
|
COMPILE_ARGS += --trace-fst
|
||||||
|
@ -202,7 +202,8 @@ def test_fpga_core(request):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
# parameters['A'] = val
|
parameters['QUAD_CNT'] = 17
|
||||||
|
parameters['CH_CNT'] = parameters['QUAD_CNT']*4
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
||||||
|
@ -31,17 +31,19 @@ THE SOFTWARE.
|
|||||||
/*
|
/*
|
||||||
* Testbench top-level module
|
* Testbench top-level module
|
||||||
*/
|
*/
|
||||||
module test_fpga_core ();
|
module test_fpga_core #
|
||||||
|
(
|
||||||
|
parameter QUAD_CNT = 17,
|
||||||
|
parameter CH_CNT = QUAD_CNT*4
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input wire clk,
|
||||||
|
input wire rst
|
||||||
|
);
|
||||||
|
|
||||||
genvar n;
|
genvar n;
|
||||||
|
|
||||||
wire clk;
|
|
||||||
wire rst;
|
|
||||||
|
|
||||||
// XGMII 10G PHY
|
// XGMII 10G PHY
|
||||||
parameter QUAD_CNT = 17;
|
|
||||||
parameter CH_CNT = QUAD_CNT*4;
|
|
||||||
|
|
||||||
wire [CH_CNT-1:0] eth_tx_clk;
|
wire [CH_CNT-1:0] eth_tx_clk;
|
||||||
wire [CH_CNT-1:0] eth_tx_rst;
|
wire [CH_CNT-1:0] eth_tx_rst;
|
||||||
wire [CH_CNT*64-1:0] eth_txd;
|
wire [CH_CNT*64-1:0] eth_txd;
|
||||||
@ -77,7 +79,9 @@ end
|
|||||||
|
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
fpga_core
|
fpga_core #(
|
||||||
|
.CH_CNT(CH_CNT)
|
||||||
|
)
|
||||||
core_inst (
|
core_inst (
|
||||||
/*
|
/*
|
||||||
* Clock: 156.25 MHz
|
* Clock: 156.25 MHz
|
||||||
|
@ -29,6 +29,11 @@ create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
|
|||||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
||||||
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
||||||
|
|
||||||
|
# User SMA clock J34/J35
|
||||||
|
#set_property -dict {LOC AR14 IOSTANDARD LVDS} [get_ports user_sma_clk_p]
|
||||||
|
#set_property -dict {LOC AT14 IOSTANDARD LVDS} [get_ports user_sma_clk_n]
|
||||||
|
#create_clock -period 8.000 -name user_sma_clk [get_ports user_sma_clk_p]
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||||
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||||
|
@ -29,6 +29,11 @@ create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
|
|||||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
||||||
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
||||||
|
|
||||||
|
# User SMA clock J34/J35
|
||||||
|
#set_property -dict {LOC AR14 IOSTANDARD LVDS} [get_ports user_sma_clk_p]
|
||||||
|
#set_property -dict {LOC AT14 IOSTANDARD LVDS} [get_ports user_sma_clk_n]
|
||||||
|
#create_clock -period 8.000 -name user_sma_clk [get_ports user_sma_clk_p]
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||||
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||||
|
@ -35,6 +35,11 @@ create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
|
|||||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
||||||
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
||||||
|
|
||||||
|
# User SMA clock J34/J35
|
||||||
|
#set_property -dict {LOC R32 IOSTANDARD LVDS} [get_ports user_sma_clk_p]
|
||||||
|
#set_property -dict {LOC P32 IOSTANDARD LVDS} [get_ports user_sma_clk_n]
|
||||||
|
#create_clock -period 8.000 -name user_sma_clk [get_ports user_sma_clk_p]
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||||
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||||
|
@ -35,6 +35,11 @@ create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
|
|||||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
||||||
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
||||||
|
|
||||||
|
# User SMA clock J34/J35
|
||||||
|
#set_property -dict {LOC R32 IOSTANDARD LVDS} [get_ports user_sma_clk_p]
|
||||||
|
#set_property -dict {LOC P32 IOSTANDARD LVDS} [get_ports user_sma_clk_n]
|
||||||
|
#create_clock -period 8.000 -name user_sma_clk [get_ports user_sma_clk_p]
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||||
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||||
|
@ -35,6 +35,11 @@ create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
|
|||||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
|
||||||
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
|
||||||
|
|
||||||
|
# User SMA clock J34/J35
|
||||||
|
#set_property -dict {LOC R32 IOSTANDARD LVDS} [get_ports user_sma_clk_p]
|
||||||
|
#set_property -dict {LOC P32 IOSTANDARD LVDS} [get_ports user_sma_clk_n]
|
||||||
|
#create_clock -period 8.000 -name user_sma_clk [get_ports user_sma_clk_p]
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||||
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||||
|
@ -491,8 +491,6 @@ always @(posedge output_clk) begin
|
|||||||
ts_capt_valid_reg <= 1'b1;
|
ts_capt_valid_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
ts_sync_valid_reg <= 1'b0;
|
|
||||||
|
|
||||||
if (src_sync_sync2_reg ^ src_sync_sync3_reg) begin
|
if (src_sync_sync2_reg ^ src_sync_sync3_reg) begin
|
||||||
// store captured source TS
|
// store captured source TS
|
||||||
if (TS_WIDTH == 96) begin
|
if (TS_WIDTH == 96) begin
|
||||||
@ -501,7 +499,11 @@ always @(posedge output_clk) begin
|
|||||||
src_ts_ns_sync_reg <= src_ts_ns_capt_reg;
|
src_ts_ns_sync_reg <= src_ts_ns_capt_reg;
|
||||||
src_ts_step_sync_reg <= src_ts_step_capt_reg;
|
src_ts_step_sync_reg <= src_ts_step_capt_reg;
|
||||||
|
|
||||||
ts_sync_valid_reg <= ts_capt_valid_reg;
|
ts_sync_valid_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (ts_sync_valid_reg && ts_capt_valid_reg) begin
|
||||||
|
ts_sync_valid_reg <= 1'b0;
|
||||||
ts_capt_valid_reg <= 1'b0;
|
ts_capt_valid_reg <= 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -595,7 +597,7 @@ always @* begin
|
|||||||
ts_ns_next = ts_ns_reg + period_ns_reg;
|
ts_ns_next = ts_ns_reg + period_ns_reg;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (ts_sync_valid_reg) begin
|
if (ts_sync_valid_reg && ts_capt_valid_reg) begin
|
||||||
// Read new value
|
// Read new value
|
||||||
if (TS_WIDTH == 96) begin
|
if (TS_WIDTH == 96) begin
|
||||||
if (src_ts_step_sync_reg || load_ts_reg) begin
|
if (src_ts_step_sync_reg || load_ts_reg) begin
|
||||||
@ -672,19 +674,19 @@ always @* begin
|
|||||||
// PI control
|
// PI control
|
||||||
|
|
||||||
// gain scheduling
|
// gain scheduling
|
||||||
if (!ts_ns_diff_reg[8+CMP_FNS_WIDTH]) begin
|
casez (ts_ns_diff_reg[9+CMP_FNS_WIDTH-5 +: 5])
|
||||||
if (ts_ns_diff_reg[4+CMP_FNS_WIDTH +: 4]) begin
|
5'b01zzz: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b1;
|
5'b001zz: gain_sel_next = 1'b1;
|
||||||
end else begin
|
5'b0001z: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b0;
|
5'b00001: gain_sel_next = 1'b1;
|
||||||
end
|
5'b00000: gain_sel_next = 1'b0;
|
||||||
end else begin
|
5'b11111: gain_sel_next = 1'b0;
|
||||||
if (~ts_ns_diff_reg[4+CMP_FNS_WIDTH +: 4]) begin
|
5'b11110: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b1;
|
5'b1110z: gain_sel_next = 1'b1;
|
||||||
end else begin
|
5'b110zz: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b0;
|
5'b10zzz: gain_sel_next = 1'b1;
|
||||||
end
|
default: gain_sel_next = 1'b0;
|
||||||
end
|
endcase
|
||||||
|
|
||||||
// time integral of error
|
// time integral of error
|
||||||
case (gain_sel_reg)
|
case (gain_sel_reg)
|
||||||
|
@ -89,7 +89,7 @@ localparam LOG_RATE = 3;
|
|||||||
|
|
||||||
localparam PHASE_CNT_W = LOG_RATE;
|
localparam PHASE_CNT_W = LOG_RATE;
|
||||||
localparam PHASE_ACC_W = PHASE_CNT_W+16;
|
localparam PHASE_ACC_W = PHASE_CNT_W+16;
|
||||||
localparam LOAD_CNT_W = 8-LOG_RATE;
|
localparam LOAD_CNT_W = 8-LOG_RATE-1;
|
||||||
|
|
||||||
localparam LOG_SAMPLE_SYNC_RATE = 4;
|
localparam LOG_SAMPLE_SYNC_RATE = 4;
|
||||||
localparam SAMPLE_ACC_W = LOG_SAMPLE_SYNC_RATE+2;
|
localparam SAMPLE_ACC_W = LOG_SAMPLE_SYNC_RATE+2;
|
||||||
@ -225,8 +225,6 @@ reg [PERIOD_NS_W+32-1:0] src_period_shadow_reg = 0;
|
|||||||
|
|
||||||
reg [9+SRC_FNS_W-1:0] src_ns_reg = 0;
|
reg [9+SRC_FNS_W-1:0] src_ns_reg = 0;
|
||||||
reg [9+32-1:0] src_ns_shadow_reg = 0;
|
reg [9+32-1:0] src_ns_shadow_reg = 0;
|
||||||
reg src_fns_shadow_valid_reg = 1'b0;
|
|
||||||
reg src_ns_shadow_valid_reg = 1'b0;
|
|
||||||
|
|
||||||
always @(posedge ptp_clk) begin
|
always @(posedge ptp_clk) begin
|
||||||
src_load_reg <= 1'b0;
|
src_load_reg <= 1'b0;
|
||||||
@ -242,15 +240,12 @@ always @(posedge ptp_clk) begin
|
|||||||
if (td_tvalid_reg) begin
|
if (td_tvalid_reg) begin
|
||||||
if (td_tid_reg[3:0] == 4'd6) begin
|
if (td_tid_reg[3:0] == 4'd6) begin
|
||||||
src_ns_shadow_reg[15:0] <= td_tdata_reg;
|
src_ns_shadow_reg[15:0] <= td_tdata_reg;
|
||||||
src_fns_shadow_valid_reg <= 1'b0;
|
|
||||||
end
|
end
|
||||||
if (td_tid_reg[3:0] == 4'd7) begin
|
if (td_tid_reg[3:0] == 4'd7) begin
|
||||||
src_ns_shadow_reg[31:16] <= td_tdata_reg;
|
src_ns_shadow_reg[31:16] <= td_tdata_reg;
|
||||||
src_fns_shadow_valid_reg <= 1'b1;
|
|
||||||
end
|
end
|
||||||
if (td_tid_reg[3:0] == 4'd8) begin
|
if (td_tid_reg[3:0] == 4'd8) begin
|
||||||
src_ns_shadow_reg[40:32] <= td_tdata_reg;
|
src_ns_shadow_reg[40:32] <= td_tdata_reg;
|
||||||
src_ns_shadow_valid_reg <= 1'b1;
|
|
||||||
end
|
end
|
||||||
if (td_tid_reg[3:0] == 4'd11) begin
|
if (td_tid_reg[3:0] == 4'd11) begin
|
||||||
src_period_shadow_reg[15:0] <= td_tdata_reg;
|
src_period_shadow_reg[15:0] <= td_tdata_reg;
|
||||||
@ -264,12 +259,9 @@ always @(posedge ptp_clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (src_load_reg) begin
|
if (src_load_reg) begin
|
||||||
if (src_ns_shadow_valid_reg && src_fns_shadow_valid_reg) begin
|
|
||||||
src_ns_reg <= src_ns_shadow_reg >> (32-SRC_FNS_W);
|
src_ns_reg <= src_ns_shadow_reg >> (32-SRC_FNS_W);
|
||||||
end
|
|
||||||
src_fns_shadow_valid_reg <= 1'b0;
|
|
||||||
src_ns_shadow_valid_reg <= 1'b0;
|
|
||||||
src_period_reg <= src_period_shadow_reg;
|
src_period_reg <= src_period_shadow_reg;
|
||||||
|
src_sync_reg <= 1'b1;
|
||||||
src_marker_reg <= !src_marker_reg;
|
src_marker_reg <= !src_marker_reg;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -435,19 +427,17 @@ always @* begin
|
|||||||
// updated sampled dst_phase error
|
// updated sampled dst_phase error
|
||||||
|
|
||||||
// gain scheduling
|
// gain scheduling
|
||||||
if (!sample_acc_sync_reg[SAMPLE_ACC_W-1]) begin
|
casez (sample_acc_sync_reg[SAMPLE_ACC_W-4 +: 4])
|
||||||
if (sample_acc_sync_reg[SAMPLE_ACC_W-4 +: 3]) begin
|
4'b01zz: dst_gain_sel_next = 1'b1;
|
||||||
dst_gain_sel_next = 1'b1;
|
4'b001z: dst_gain_sel_next = 1'b1;
|
||||||
end else begin
|
4'b0001: dst_gain_sel_next = 1'b1;
|
||||||
dst_gain_sel_next = 1'b0;
|
4'b0000: dst_gain_sel_next = 1'b0;
|
||||||
end
|
4'b1111: dst_gain_sel_next = 1'b0;
|
||||||
end else begin
|
4'b1110: dst_gain_sel_next = 1'b1;
|
||||||
if (~sample_acc_sync_reg[SAMPLE_ACC_W-4 +: 3]) begin
|
4'b110z: dst_gain_sel_next = 1'b1;
|
||||||
dst_gain_sel_next = 1'b1;
|
4'b10zz: dst_gain_sel_next = 1'b1;
|
||||||
end else begin
|
default: dst_gain_sel_next = 1'b0;
|
||||||
dst_gain_sel_next = 1'b0;
|
endcase
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// time integral of error
|
// time integral of error
|
||||||
case (dst_gain_sel_reg)
|
case (dst_gain_sel_reg)
|
||||||
@ -530,17 +520,16 @@ always @(posedge clk) begin
|
|||||||
dst_sync_reg <= !dst_sync_reg;
|
dst_sync_reg <= !dst_sync_reg;
|
||||||
ts_capt_valid_reg <= 1'b1;
|
ts_capt_valid_reg <= 1'b1;
|
||||||
|
|
||||||
|
if (dst_sync_reg) begin
|
||||||
dst_load_cnt_reg <= dst_load_cnt_reg + 1;
|
dst_load_cnt_reg <= dst_load_cnt_reg + 1;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
ts_sync_valid_reg <= 1'b0;
|
|
||||||
|
|
||||||
if (src_sync_sync2_reg ^ src_sync_sync3_reg) begin
|
if (src_sync_sync2_reg ^ src_sync_sync3_reg) begin
|
||||||
// store captured source TS
|
// store captured source TS
|
||||||
src_ns_sync_reg <= src_ns_reg >> (SRC_FNS_W-CMP_FNS_W);
|
src_ns_sync_reg <= src_ns_reg >> (SRC_FNS_W-CMP_FNS_W);
|
||||||
|
|
||||||
ts_sync_valid_reg <= ts_capt_valid_reg;
|
ts_sync_valid_reg <= 1'b1;
|
||||||
ts_capt_valid_reg <= 1'b0;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (src_marker_sync2_reg ^ src_marker_sync3_reg) begin
|
if (src_marker_sync2_reg ^ src_marker_sync3_reg) begin
|
||||||
@ -548,9 +537,12 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
phase_err_out_valid_reg <= 1'b0;
|
phase_err_out_valid_reg <= 1'b0;
|
||||||
if (ts_sync_valid_reg) begin
|
if (ts_sync_valid_reg && ts_capt_valid_reg) begin
|
||||||
// coarse phase locking
|
// coarse phase locking
|
||||||
|
|
||||||
|
ts_sync_valid_reg <= 1'b0;
|
||||||
|
ts_capt_valid_reg <= 1'b0;
|
||||||
|
|
||||||
// phase and frequency detector
|
// phase and frequency detector
|
||||||
phase_last_src_reg <= src_ns_sync_reg[8+CMP_FNS_W];
|
phase_last_src_reg <= src_ns_sync_reg[8+CMP_FNS_W];
|
||||||
phase_last_dst_reg <= dst_ns_capt_reg[8+CMP_FNS_W];
|
phase_last_dst_reg <= dst_ns_capt_reg[8+CMP_FNS_W];
|
||||||
@ -696,6 +688,10 @@ always @* begin
|
|||||||
// extract data
|
// extract data
|
||||||
if (dst_td_tvalid_reg) begin
|
if (dst_td_tvalid_reg) begin
|
||||||
if (TS_TOD_EN) begin
|
if (TS_TOD_EN) begin
|
||||||
|
if (dst_td_tid_reg[3:0] == 4'd1) begin
|
||||||
|
// prevent stale data from being used in time sync
|
||||||
|
dst_tod_shadow_valid_next = 1'b0;
|
||||||
|
end
|
||||||
if (dst_td_tid_reg == {4'd0, 4'd1}) begin
|
if (dst_td_tid_reg == {4'd0, 4'd1}) begin
|
||||||
dst_tod_ns_shadow_next[15:0] = dst_td_tdata_reg;
|
dst_tod_ns_shadow_next[15:0] = dst_td_tdata_reg;
|
||||||
dst_tod_shadow_valid_next = 1'b0;
|
dst_tod_shadow_valid_next = 1'b0;
|
||||||
@ -749,7 +745,7 @@ always @* begin
|
|||||||
ts_rel_ns_next = ({ts_rel_ns_reg, ts_fns_reg} + period_ns_reg) >> FNS_W;
|
ts_rel_ns_next = ({ts_rel_ns_reg, ts_fns_reg} + period_ns_reg) >> FNS_W;
|
||||||
|
|
||||||
if (TS_REL_EN) begin
|
if (TS_REL_EN) begin
|
||||||
if (dst_update_reg && dst_rel_shadow_valid_reg && (dst_load_cnt_reg == {LOAD_CNT_W{1'b1}})) begin
|
if (dst_update_reg && !dst_sync_reg && dst_rel_shadow_valid_reg && (dst_load_cnt_reg == 0)) begin
|
||||||
// check timestamp MSBs
|
// check timestamp MSBs
|
||||||
if (dst_rel_step_shadow_reg || ts_rel_load_ts_reg) begin
|
if (dst_rel_step_shadow_reg || ts_rel_load_ts_reg) begin
|
||||||
// input stepped
|
// input stepped
|
||||||
@ -797,7 +793,7 @@ always @* begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dst_update_reg && dst_tod_shadow_valid_reg && (dst_load_cnt_reg == {LOAD_CNT_W{1'b1}})) begin
|
if (dst_update_reg && !dst_sync_reg && dst_tod_shadow_valid_reg && (dst_load_cnt_reg == 0)) begin
|
||||||
// check timestamp MSBs
|
// check timestamp MSBs
|
||||||
if (dst_tod_step_shadow_reg || ts_tod_load_ts_reg) begin
|
if (dst_tod_step_shadow_reg || ts_tod_load_ts_reg) begin
|
||||||
// input stepped
|
// input stepped
|
||||||
@ -827,7 +823,7 @@ always @* begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (ts_sync_valid_reg) begin
|
if (ts_sync_valid_reg && ts_capt_valid_reg) begin
|
||||||
// compute difference
|
// compute difference
|
||||||
ts_ns_diff_valid_next = freq_locked_reg;
|
ts_ns_diff_valid_next = freq_locked_reg;
|
||||||
ts_ns_diff_next = src_ns_sync_reg - dst_ns_capt_reg;
|
ts_ns_diff_next = src_ns_sync_reg - dst_ns_capt_reg;
|
||||||
@ -859,19 +855,19 @@ always @* begin
|
|||||||
// PI control
|
// PI control
|
||||||
|
|
||||||
// gain scheduling
|
// gain scheduling
|
||||||
if (!ts_ns_diff_reg[8+CMP_FNS_W]) begin
|
casez (ts_ns_diff_reg[9+CMP_FNS_W-5 +: 5])
|
||||||
if (ts_ns_diff_reg[4+CMP_FNS_W +: 4]) begin
|
5'b01zzz: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b1;
|
5'b001zz: gain_sel_next = 1'b1;
|
||||||
end else begin
|
5'b0001z: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b0;
|
5'b00001: gain_sel_next = 1'b1;
|
||||||
end
|
5'b00000: gain_sel_next = 1'b0;
|
||||||
end else begin
|
5'b11111: gain_sel_next = 1'b0;
|
||||||
if (~ts_ns_diff_reg[4+CMP_FNS_W +: 4]) begin
|
5'b11110: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b1;
|
5'b1110z: gain_sel_next = 1'b1;
|
||||||
end else begin
|
5'b110zz: gain_sel_next = 1'b1;
|
||||||
gain_sel_next = 1'b0;
|
5'b10zzz: gain_sel_next = 1'b1;
|
||||||
end
|
default: gain_sel_next = 1'b0;
|
||||||
end
|
endcase
|
||||||
|
|
||||||
// time integral of error
|
// time integral of error
|
||||||
case (gain_sel_reg)
|
case (gain_sel_reg)
|
||||||
|
@ -154,10 +154,9 @@ reg [3:0] update_state_reg = 0;
|
|||||||
reg [47:0] adder_a_reg = 0;
|
reg [47:0] adder_a_reg = 0;
|
||||||
reg [47:0] adder_b_reg = 0;
|
reg [47:0] adder_b_reg = 0;
|
||||||
reg adder_cin_reg = 0;
|
reg adder_cin_reg = 0;
|
||||||
wire [47:0] adder_sum;
|
reg [47:0] adder_sum_reg = 0;
|
||||||
wire adder_cout;
|
reg adder_cout_reg = 0;
|
||||||
|
reg adder_busy_reg = 0;
|
||||||
assign {adder_cout, adder_sum} = adder_a_reg + adder_b_reg + adder_cin_reg;
|
|
||||||
|
|
||||||
assign input_ts_tod_ready = input_ts_tod_ready_reg;
|
assign input_ts_tod_ready = input_ts_tod_ready_reg;
|
||||||
assign input_ts_tod_offset_ready = input_ts_tod_offset_ready_reg;
|
assign input_ts_tod_offset_ready = input_ts_tod_offset_ready_reg;
|
||||||
@ -225,8 +224,7 @@ always @(posedge clk) begin
|
|||||||
pps_gen_ns_reg <= pps_gen_ns_reg + pps_gen_ns_inc_reg;
|
pps_gen_ns_reg <= pps_gen_ns_reg + pps_gen_ns_inc_reg;
|
||||||
|
|
||||||
if (!pps_gen_ns_reg[30]) begin
|
if (!pps_gen_ns_reg[30]) begin
|
||||||
// pps_delay_reg <= 14*17 + 32 + 1;
|
pps_delay_reg <= 14*17 + 32 + 240;
|
||||||
pps_delay_reg <= 14*17 + 32 + 248;
|
|
||||||
pps_gen_ns_reg[30] <= 1'b1;
|
pps_gen_ns_reg[30] <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -245,6 +243,30 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// update state machine
|
// update state machine
|
||||||
|
{adder_cout_reg, adder_sum_reg} <= adder_a_reg + adder_b_reg + adder_cin_reg;
|
||||||
|
adder_busy_reg <= 1'b0;
|
||||||
|
|
||||||
|
// computes the following:
|
||||||
|
// {ts_inc_ns_reg, ts_fns_reg} = drift_acc_reg + $signed(input_ts_offset_fns) + {period_ns_reg, period_fns_reg} * 256 + ts_fns_reg
|
||||||
|
// ts_rel_ns_reg = ts_rel_ns_reg + ts_inc_ns_reg + $signed(input_ts_rel_offset_ns);
|
||||||
|
// ts_tod_ns_reg = ts_tod_ns_reg + ts_inc_ns_reg + $signed(input_ts_tod_offset_ns);
|
||||||
|
// if that borrowed,
|
||||||
|
// ts_tod_ns_reg = ts_tod_ns_reg + NS_PER_S
|
||||||
|
// ts_tod_s_reg = ts_tod_s_reg - 1
|
||||||
|
// else
|
||||||
|
// pps_gen_ns_reg = ts_tod_ns_reg - NS_PER_S
|
||||||
|
// if that did not borrow,
|
||||||
|
// ts_tod_ns_reg = ts_tod_ns_reg - NS_PER_S
|
||||||
|
// ts_tod_s_reg = ts_tod_s_reg + 1
|
||||||
|
// ts_tod_offset_ns_reg = ts_tod_ns_reg - ts_rel_ns_reg
|
||||||
|
// if ts_tod_ns_reg[29]
|
||||||
|
// ts_tod_alt_offset_ns_reg = ts_tod_offset_ns_reg - NS_PER_S
|
||||||
|
// ts_tod_alt_s_reg = ts_tod_s_reg + 1
|
||||||
|
// else
|
||||||
|
// ts_tod_alt_offset_ns_reg = ts_tod_offset_ns_reg + NS_PER_S
|
||||||
|
// ts_tod_alt_s_reg = ts_tod_s_reg - 1
|
||||||
|
|
||||||
|
if (!adder_busy_reg) begin
|
||||||
case (update_state_reg)
|
case (update_state_reg)
|
||||||
0: begin
|
0: begin
|
||||||
// idle
|
// idle
|
||||||
@ -277,31 +299,44 @@ always @(posedge clk) begin
|
|||||||
drift_acc_reg <= 0;
|
drift_acc_reg <= 0;
|
||||||
input_ts_offset_ready_reg <= input_ts_offset_valid;
|
input_ts_offset_ready_reg <= input_ts_offset_valid;
|
||||||
update_state_reg <= 1;
|
update_state_reg <= 1;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
update_state_reg <= 0;
|
update_state_reg <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
1: begin
|
1: begin
|
||||||
// compute period 2 - add drift and offset to period
|
// compute period 2 - add drift and offset to period
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= {period_ns_reg, period_fns_reg, 8'd0};
|
adder_b_reg <= {period_ns_reg, period_fns_reg, 8'd0};
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 2;
|
update_state_reg <= 2;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
2: begin
|
2: begin
|
||||||
// compute next fns
|
// compute next fns
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= ts_fns_reg;
|
adder_b_reg <= ts_fns_reg;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 3;
|
update_state_reg <= 3;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
3: begin
|
3: begin
|
||||||
// store fns; compute relative timestamp 1 - add previous value and offset
|
// store fns
|
||||||
{ts_inc_ns_reg, ts_fns_reg} <= {adder_cout, adder_sum};
|
{ts_inc_ns_reg, ts_fns_reg} <= {adder_cout_reg, adder_sum_reg};
|
||||||
|
|
||||||
|
// compute relative timestamp 1 - add previous value and increment
|
||||||
adder_a_reg <= ts_rel_ns_reg;
|
adder_a_reg <= ts_rel_ns_reg;
|
||||||
|
adder_b_reg <= {adder_cout_reg, adder_sum_reg} >> FNS_W; // ts_inc_ns_reg
|
||||||
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
|
update_state_reg <= 4;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
4: begin
|
||||||
|
// compute relative timestamp 2 - add offset
|
||||||
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= 0;
|
adder_b_reg <= 0;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
@ -312,29 +347,24 @@ always @(posedge clk) begin
|
|||||||
ts_rel_updated_reg <= 1'b1;
|
ts_rel_updated_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
update_state_reg <= 4;
|
|
||||||
end
|
|
||||||
4: begin
|
|
||||||
// compute relative timestamp 2 - add increment
|
|
||||||
adder_a_reg <= adder_sum;
|
|
||||||
adder_b_reg <= ts_inc_ns_reg;
|
|
||||||
adder_cin_reg <= 0;
|
|
||||||
|
|
||||||
update_state_reg <= 5;
|
update_state_reg <= 5;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
5: begin
|
5: begin
|
||||||
// store relative timestamp; compute ToD timestamp 1 - add previous value and increment
|
// store relative timestamp
|
||||||
ts_rel_ns_reg <= adder_sum;
|
ts_rel_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
|
// compute ToD timestamp 1 - add previous value and increment
|
||||||
adder_a_reg <= ts_tod_ns_reg;
|
adder_a_reg <= ts_tod_ns_reg;
|
||||||
adder_b_reg <= ts_inc_ns_reg;
|
adder_b_reg <= ts_inc_ns_reg;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 6;
|
update_state_reg <= 6;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
6: begin
|
6: begin
|
||||||
// compute ToD timestamp 2 - add offset
|
// compute ToD timestamp 2 - add offset
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= 0;
|
adder_b_reg <= 0;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
@ -346,30 +376,33 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
update_state_reg <= 7;
|
update_state_reg <= 7;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
7: begin
|
7: begin
|
||||||
// compute ToD timestamp 2 - check for underflow/overflow
|
// compute ToD timestamp 3 - check for underflow/overflow
|
||||||
ts_tod_ns_reg <= adder_sum;
|
ts_tod_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
if (adder_b_reg[47] && !adder_cout) begin
|
if (adder_b_reg[47] && !adder_cout_reg) begin
|
||||||
// borrowed; add 1 billion
|
// borrowed; add 1 billion
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= NS_PER_S;
|
adder_b_reg <= NS_PER_S;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 8;
|
update_state_reg <= 8;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
// did not borrow; subtract 1 billion to check for overflow
|
// did not borrow; subtract 1 billion to check for overflow
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= -NS_PER_S;
|
adder_b_reg <= -NS_PER_S;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 9;
|
update_state_reg <= 9;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
8: begin
|
8: begin
|
||||||
// seconds decrement
|
// seconds decrement
|
||||||
ts_tod_ns_reg <= adder_sum;
|
ts_tod_ns_reg <= adder_sum_reg;
|
||||||
pps_gen_ns_reg[30] <= 1'b1;
|
pps_gen_ns_reg[30] <= 1'b1;
|
||||||
|
|
||||||
adder_a_reg <= ts_tod_s_reg;
|
adder_a_reg <= ts_tod_s_reg;
|
||||||
@ -377,20 +410,21 @@ always @(posedge clk) begin
|
|||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 10;
|
update_state_reg <= 10;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
9: begin
|
9: begin
|
||||||
// seconds increment
|
// seconds increment
|
||||||
pps_gen_ns_reg <= adder_sum;
|
pps_gen_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
if (!adder_cout) begin
|
if (!adder_cout_reg) begin
|
||||||
// borrowed; leave seconds alone
|
// borrowed; leave seconds alone
|
||||||
|
|
||||||
adder_a_reg <= ts_tod_s_reg;
|
adder_a_reg <= ts_tod_s_reg;
|
||||||
adder_b_reg <= 0;
|
adder_b_reg <= 0;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
// did not borrow; decrement seconds
|
// did not borrow; increment seconds
|
||||||
ts_tod_ns_reg <= adder_sum;
|
ts_tod_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
adder_a_reg <= ts_tod_s_reg;
|
adder_a_reg <= ts_tod_s_reg;
|
||||||
adder_b_reg <= 1;
|
adder_b_reg <= 1;
|
||||||
@ -398,28 +432,25 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
update_state_reg <= 10;
|
update_state_reg <= 10;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
10: begin
|
10: begin
|
||||||
// store seconds; compute offset
|
// store seconds
|
||||||
ts_tod_s_reg <= adder_sum;
|
ts_tod_s_reg <= adder_sum_reg;
|
||||||
|
|
||||||
if (adder_sum == ts_tod_alt_s_reg) begin
|
|
||||||
// store previous offset as alternate
|
|
||||||
ts_tod_alt_s_reg <= ts_tod_s_reg;
|
|
||||||
ts_tod_alt_offset_ns_reg <= ts_tod_offset_ns_reg;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
// compute offset
|
||||||
adder_a_reg <= ts_tod_ns_reg;
|
adder_a_reg <= ts_tod_ns_reg;
|
||||||
adder_b_reg <= ~ts_rel_ns_reg;
|
adder_b_reg <= ~ts_rel_ns_reg;
|
||||||
adder_cin_reg <= 1;
|
adder_cin_reg <= 1;
|
||||||
|
|
||||||
update_state_reg <= 11;
|
update_state_reg <= 11;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
11: begin
|
11: begin
|
||||||
// store offset
|
// store offset
|
||||||
ts_tod_offset_ns_reg <= adder_sum;
|
ts_tod_offset_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
adder_a_reg <= adder_sum;
|
adder_a_reg <= adder_sum_reg;
|
||||||
adder_b_reg <= -NS_PER_S;
|
adder_b_reg <= -NS_PER_S;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
@ -427,41 +458,45 @@ always @(posedge clk) begin
|
|||||||
// latter half of second; compute offset for next second
|
// latter half of second; compute offset for next second
|
||||||
adder_b_reg <= -NS_PER_S;
|
adder_b_reg <= -NS_PER_S;
|
||||||
update_state_reg <= 12;
|
update_state_reg <= 12;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
// former half of second; compute offset for previous second
|
// former half of second; compute offset for previous second
|
||||||
adder_b_reg <= NS_PER_S;
|
adder_b_reg <= NS_PER_S;
|
||||||
update_state_reg <= 14;
|
update_state_reg <= 14;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
12: begin
|
12: begin
|
||||||
// store alternate offset for next second
|
// store alternate offset for next second
|
||||||
ts_tod_alt_offset_ns_reg <= adder_sum;
|
ts_tod_alt_offset_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
adder_a_reg <= ts_tod_s_reg;
|
adder_a_reg <= ts_tod_s_reg;
|
||||||
adder_b_reg <= 1;
|
adder_b_reg <= 1;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 13;
|
update_state_reg <= 13;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
13: begin
|
13: begin
|
||||||
// store alternate second for next second
|
// store alternate second for next second
|
||||||
ts_tod_alt_s_reg <= adder_sum;
|
ts_tod_alt_s_reg <= adder_sum_reg;
|
||||||
|
|
||||||
update_state_reg <= 0;
|
update_state_reg <= 0;
|
||||||
end
|
end
|
||||||
14: begin
|
14: begin
|
||||||
// store alternate offset for previous second
|
// store alternate offset for previous second
|
||||||
ts_tod_alt_offset_ns_reg <= adder_sum;
|
ts_tod_alt_offset_ns_reg <= adder_sum_reg;
|
||||||
|
|
||||||
adder_a_reg <= ts_tod_s_reg;
|
adder_a_reg <= ts_tod_s_reg;
|
||||||
adder_b_reg <= -1;
|
adder_b_reg <= -1;
|
||||||
adder_cin_reg <= 0;
|
adder_cin_reg <= 0;
|
||||||
|
|
||||||
update_state_reg <= 15;
|
update_state_reg <= 15;
|
||||||
|
adder_busy_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
15: begin
|
15: begin
|
||||||
// store alternate second for previous second
|
// store alternate second for previous second
|
||||||
ts_tod_alt_s_reg <= adder_sum;
|
ts_tod_alt_s_reg <= adder_sum_reg;
|
||||||
|
|
||||||
update_state_reg <= 0;
|
update_state_reg <= 0;
|
||||||
end
|
end
|
||||||
@ -470,6 +505,7 @@ always @(posedge clk) begin
|
|||||||
update_state_reg <= 0;
|
update_state_reg <= 0;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
// time distribution message generation
|
// time distribution message generation
|
||||||
td_shift_reg <= {1'b1, td_shift_reg} >> 1;
|
td_shift_reg <= {1'b1, td_shift_reg} >> 1;
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
# Ethernet MAC timing constraints
|
# Ethernet MAC timing constraints
|
||||||
|
|
||||||
foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g || REF_NAME == eth_mac_1g || \
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "eth_mac_(1g|10g)(__\w+__\d+)?" ||
|
||||||
ORIG_REF_NAME == eth_mac_10g || REF_NAME == eth_mac_10g)}] {
|
REF_NAME =~ "eth_mac_(1g|10g)(__\w+__\d+)?")}] {
|
||||||
puts "Inserting timing constraints for Ethernet MAC instance $inst"
|
puts "Inserting timing constraints for Ethernet MAC instance $inst"
|
||||||
|
|
||||||
set sync_ffs [get_cells -quiet -hier -regexp ".*/mac_ctrl.tx_lfc_req_sync_reg_\[1234\]_reg" -filter "PARENT == $inst"]
|
set sync_ffs [get_cells -quiet -hier -regexp ".*/mac_ctrl.tx_lfc_req_sync_reg_\[1234\]_reg" -filter "PARENT == $inst"]
|
||||||
|
@ -20,42 +20,43 @@
|
|||||||
|
|
||||||
# GMII Gigabit Ethernet MAC timing constraints
|
# GMII Gigabit Ethernet MAC timing constraints
|
||||||
|
|
||||||
foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_gmii || REF_NAME == eth_mac_1g_gmii)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "eth_mac_1g_gmii(__\w+__\d+)?" ||
|
||||||
puts "Inserting timing constraints for eth_mac_1g_gmii instance $mac_inst"
|
REF_NAME =~ "eth_mac_1g_gmii(__\w+__\d+)?")}] {
|
||||||
|
puts "Inserting timing constraints for eth_mac_1g_gmii instance $inst"
|
||||||
|
|
||||||
set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $select_ffs]} {
|
if {[llength $select_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $select_ffs
|
set_property ASYNC_REG TRUE $select_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/mii_select_reg_reg/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/tx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/mii_select_reg_reg] -to [get_cells $inst/tx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
|
|
||||||
set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $select_ffs]} {
|
if {[llength $select_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $select_ffs
|
set_property ASYNC_REG TRUE $select_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/mii_select_reg_reg/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/rx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/mii_select_reg_reg] -to [get_cells $inst/rx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
|
|
||||||
set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $prescale_ffs]} {
|
if {[llength $prescale_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $prescale_ffs
|
set_property ASYNC_REG TRUE $prescale_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_prescale_reg[2]/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/rx_prescale_reg[2]/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/rx_prescale_reg[2]] -to [get_cells $mac_inst/rx_prescale_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/rx_prescale_reg[2]] -to [get_cells $inst/rx_prescale_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,42 +20,43 @@
|
|||||||
|
|
||||||
# RGMII Gigabit Ethernet MAC timing constraints
|
# RGMII Gigabit Ethernet MAC timing constraints
|
||||||
|
|
||||||
foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_rgmii || REF_NAME == eth_mac_1g_rgmii)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "eth_mac_1g_rgmii(__\w+__\d+)?" ||
|
||||||
puts "Inserting timing constraints for eth_mac_1g_rgmii instance $mac_inst"
|
REF_NAME =~ "eth_mac_1g_rgmii(__\w+__\d+)?")}] {
|
||||||
|
puts "Inserting timing constraints for eth_mac_1g_rgmii instance $inst"
|
||||||
|
|
||||||
set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $select_ffs]} {
|
if {[llength $select_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $select_ffs
|
set_property ASYNC_REG TRUE $select_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/mii_select_reg_reg/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/tx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/mii_select_reg_reg] -to [get_cells $inst/tx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
|
|
||||||
set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $select_ffs]} {
|
if {[llength $select_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $select_ffs
|
set_property ASYNC_REG TRUE $select_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/mii_select_reg_reg/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/rx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/mii_select_reg_reg] -to [get_cells $inst/rx_mii_select_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
|
|
||||||
set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"]
|
set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $prescale_ffs]} {
|
if {[llength $prescale_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $prescale_ffs
|
set_property ASYNC_REG TRUE $prescale_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_prescale_reg[2]/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/rx_prescale_reg[2]/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/rx_prescale_reg[2]] -to [get_cells $mac_inst/rx_prescale_sync_reg[0]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/rx_prescale_reg[2]] -to [get_cells $inst/rx_prescale_sync_reg[0]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,34 +20,31 @@
|
|||||||
|
|
||||||
# Ethernet MAC with FIFO timing constraints
|
# Ethernet MAC with FIFO timing constraints
|
||||||
|
|
||||||
foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_fifo || REF_NAME == eth_mac_1g_fifo || \
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "eth_mac_(10g|1g_(gmii|rgmii)|mii)_fifo(__\w+__\d+)?" ||
|
||||||
ORIG_REF_NAME == eth_mac_10g_fifo || REF_NAME == eth_mac_10g_fifo || \
|
REF_NAME =~ "eth_mac_(10g|1g_(gmii|rgmii)|mii)_fifo(__\w+__\d+)?")}] {
|
||||||
ORIG_REF_NAME == eth_mac_1g_gmii_fifo || REF_NAME == eth_mac_1g_gmii_fifo || \
|
puts "Inserting timing constraints for ethernet MAC with FIFO instance $inst"
|
||||||
ORIG_REF_NAME == eth_mac_1g_rgmii_fifo || REF_NAME == eth_mac_1g_rgmii_fifo || \
|
|
||||||
ORIG_REF_NAME == eth_mac_mii_fifo || REF_NAME == eth_mac_mii_fifo)}] {
|
|
||||||
puts "Inserting timing constraints for ethernet MAC with FIFO instance $mac_inst"
|
|
||||||
|
|
||||||
set sync_ffs [get_cells -hier -regexp ".*/rx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $mac_inst"]
|
set sync_ffs [get_cells -hier -regexp ".*/rx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $sync_ffs]} {
|
if {[llength $sync_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $sync_ffs
|
set_property ASYNC_REG TRUE $sync_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_sync_reg_1_reg[*]/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/rx_sync_reg_1_reg[*]/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/rx_sync_reg_1_reg[*]] -to [get_cells $mac_inst/rx_sync_reg_2_reg[*]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/rx_sync_reg_1_reg[*]] -to [get_cells $inst/rx_sync_reg_2_reg[*]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
|
|
||||||
set sync_ffs [get_cells -hier -regexp ".*/tx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $mac_inst"]
|
set sync_ffs [get_cells -hier -regexp ".*/tx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
if {[llength $sync_ffs]} {
|
if {[llength $sync_ffs]} {
|
||||||
set_property ASYNC_REG TRUE $sync_ffs
|
set_property ASYNC_REG TRUE $sync_ffs
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $mac_inst/tx_sync_reg_1_reg[*]/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/tx_sync_reg_1_reg[*]/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $mac_inst/tx_sync_reg_1_reg[*]] -to [get_cells $mac_inst/tx_sync_reg_2_reg[*]] -datapath_only $src_clk_period
|
set_max_delay -from [get_cells $inst/tx_sync_reg_1_reg[*]] -to [get_cells $inst/tx_sync_reg_2_reg[*]] -datapath_only $src_clk_period
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
|
|
||||||
# GMII PHY IF timing constraints
|
# GMII PHY IF timing constraints
|
||||||
|
|
||||||
foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == gmii_phy_if || REF_NAME == gmii_phy_if)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "gmii_phy_if(__\w+__\d+)?" ||
|
||||||
puts "Inserting timing constraints for gmii_phy_if instance $if_inst"
|
REF_NAME =~ "gmii_phy_if(__\w+__\d+)?")}] {
|
||||||
|
puts "Inserting timing constraints for gmii_phy_if instance $inst"
|
||||||
|
|
||||||
# reset synchronization
|
# reset synchronization
|
||||||
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"]
|
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
set_property ASYNC_REG TRUE $reset_ffs
|
set_property ASYNC_REG TRUE $reset_ffs
|
||||||
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
|
|
||||||
# MII PHY IF timing constraints
|
# MII PHY IF timing constraints
|
||||||
|
|
||||||
foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == mii_phy_if || REF_NAME == mii_phy_if)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "mii_phy_if(__\w+__\d+)?" ||
|
||||||
puts "Inserting timing constraints for mii_phy_if instance $if_inst"
|
REF_NAME =~ "mii_phy_if(__\w+__\d+)?")}] {
|
||||||
|
puts "Inserting timing constraints for mii_phy_if instance $inst"
|
||||||
|
|
||||||
# reset synchronization
|
# reset synchronization
|
||||||
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"]
|
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
set_property ASYNC_REG TRUE $reset_ffs
|
set_property ASYNC_REG TRUE $reset_ffs
|
||||||
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
# PTP timestamp capture module
|
# PTP timestamp capture module
|
||||||
|
|
||||||
foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == ptp_clock_cdc || REF_NAME == ptp_clock_cdc)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "ptp_clock_cdc(__\w+__\d+)?" ||
|
||||||
|
REF_NAME =~ "ptp_clock_cdc(__\w+__\d+)?")}] {
|
||||||
puts "Inserting timing constraints for ptp_clock_cdc instance $inst"
|
puts "Inserting timing constraints for ptp_clock_cdc instance $inst"
|
||||||
|
|
||||||
# get clock periods
|
# get clock periods
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
# PTP time distribution leaf module
|
# PTP time distribution leaf module
|
||||||
|
|
||||||
foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == ptp_td_leaf || REF_NAME == ptp_td_leaf)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "ptp_td_leaf(__\w+__\d+)?" ||
|
||||||
|
REF_NAME =~ "ptp_td_leaf(__\w+__\d+)?")}] {
|
||||||
puts "Inserting timing constraints for ptp_td_leaf instance $inst"
|
puts "Inserting timing constraints for ptp_td_leaf instance $inst"
|
||||||
|
|
||||||
# get clock periods
|
# get clock periods
|
||||||
|
@ -20,22 +20,23 @@
|
|||||||
|
|
||||||
# RGMII PHY IF timing constraints
|
# RGMII PHY IF timing constraints
|
||||||
|
|
||||||
foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == rgmii_phy_if || REF_NAME == rgmii_phy_if)}] {
|
foreach inst [get_cells -hier -regexp -filter {(ORIG_REF_NAME =~ "rgmii_phy_if(__\w+__\d+)?" ||
|
||||||
puts "Inserting timing constraints for rgmii_phy_if instance $if_inst"
|
REF_NAME =~ "rgmii_phy_if(__\w+__\d+)?")}] {
|
||||||
|
puts "Inserting timing constraints for rgmii_phy_if instance $inst"
|
||||||
|
|
||||||
# reset synchronization
|
# reset synchronization
|
||||||
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"]
|
set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $inst"]
|
||||||
|
|
||||||
set_property ASYNC_REG TRUE $reset_ffs
|
set_property ASYNC_REG TRUE $reset_ffs
|
||||||
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]
|
||||||
|
|
||||||
# clock output
|
# clock output
|
||||||
set_property ASYNC_REG TRUE [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst]
|
set_property ASYNC_REG TRUE [get_cells $inst/clk_oddr_inst/oddr[0].oddr_inst]
|
||||||
|
|
||||||
set src_clk [get_clocks -of_objects [get_pins $if_inst/rgmii_tx_clk_1_reg/C]]
|
set src_clk [get_clocks -of_objects [get_pins $inst/rgmii_tx_clk_1_reg/C]]
|
||||||
|
|
||||||
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
set src_clk_period [if {[llength $src_clk]} {get_property -min PERIOD $src_clk} {expr 8.0}]
|
||||||
|
|
||||||
set_max_delay -from [get_cells $if_inst/rgmii_tx_clk_1_reg] -to [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr $src_clk_period/4]
|
set_max_delay -from [get_cells $inst/rgmii_tx_clk_1_reg] -to [get_cells $inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr $src_clk_period/4]
|
||||||
set_max_delay -from [get_cells $if_inst/rgmii_tx_clk_2_reg] -to [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr $src_clk_period/4]
|
set_max_delay -from [get_cells $inst/rgmii_tx_clk_2_reg] -to [get_cells $inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr $src_clk_period/4]
|
||||||
}
|
}
|
||||||
|
@ -421,6 +421,40 @@ async def run_test(dut):
|
|||||||
assert abs(mean(rel_diffs)) < 5
|
assert abs(mean(rel_diffs)) < 5
|
||||||
assert abs(mean(tod_diffs)) < 5
|
assert abs(mean(tod_diffs)) < 5
|
||||||
|
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
tb.log.info("Coherent tracking (250 MHz +0/-0.5%)")
|
||||||
|
|
||||||
|
tb.set_ptp_clock_period(6.4)
|
||||||
|
tb.set_clock_period(4.0)
|
||||||
|
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
|
period = 4.000
|
||||||
|
step = 0.0002
|
||||||
|
period_min = 4.0
|
||||||
|
period_max = 4.0*(1+0.005)
|
||||||
|
|
||||||
|
for i in range(5000):
|
||||||
|
period += step
|
||||||
|
|
||||||
|
if period <= period_min:
|
||||||
|
step = abs(step)
|
||||||
|
if period >= period_max:
|
||||||
|
step = -abs(step)
|
||||||
|
|
||||||
|
tb.set_clock_period(period)
|
||||||
|
|
||||||
|
for i in range(20):
|
||||||
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
|
assert tb.dut.locked.value.integer
|
||||||
|
|
||||||
|
rel_diffs, tod_diffs = await tb.measure_ts_diff()
|
||||||
|
tb.log.info(f"Difference (rel): {mean(rel_diffs)} ns (stdev: {stdev(rel_diffs)})")
|
||||||
|
tb.log.info(f"Difference (ToD): {mean(tod_diffs)} ns (stdev: {stdev(tod_diffs)})")
|
||||||
|
assert abs(mean(rel_diffs)) < 5
|
||||||
|
assert abs(mean(tod_diffs)) < 5
|
||||||
|
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
tb.log.info("Significantly slower (100 MHz)")
|
tb.log.info("Significantly slower (100 MHz)")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user