From bba705bac6effa394a8e78022e9f11a874dbd130 Mon Sep 17 00:00:00 2001 From: "Matthew.Blanton" Date: Mon, 12 Feb 2024 12:41:07 -0500 Subject: [PATCH 01/11] Added support for JESD204C FEC meta mode for RX and TX. --- .../axi_jesd204_common/jesd204_up_common.v | 10 +- .../jesd204/axi_jesd204_rx/axi_jesd204_rx.v | 6 +- .../jesd204/axi_jesd204_rx/jesd204_up_rx.v | 16 +- .../jesd204/axi_jesd204_tx/axi_jesd204_tx.v | 4 +- library/jesd204/jesd204_common/lfsr_input.sv | 129 ++++++ .../jesd204/jesd204_rx/jesd204_fec_decode.sv | 347 +++++++++++++++ library/jesd204/jesd204_rx/jesd204_rx.v | 9 +- .../jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv | 145 ++++++ .../jesd204/jesd204_rx/jesd204_rx_header.v | 18 +- .../jesd204/jesd204_rx/jesd204_rx_lane_64b.v | 87 +++- .../jesd204_rx_static_config.v | 5 +- .../jesd204/jesd204_tx/jesd204_fec_encode.sv | 95 ++++ library/jesd204/jesd204_tx/jesd204_tx.v | 9 +- .../jesd204/jesd204_tx/jesd204_tx_lane_64b.v | 46 +- .../jesd204_tx_static_config.v | 5 +- library/jesd204/tb/sim_jesd204_fec.sh | 16 + library/jesd204/tb/sim_jesd204_fec_encode.sh | 12 + library/jesd204/tb/sim_lfsr_input.sh | 11 + library/jesd204/tb/sim_link_layer_fec.sh | 51 +++ library/jesd204/tb/tb_jesd204_fec.sv | 151 +++++++ library/jesd204/tb/tb_jesd204_fec_encode.v | 67 +++ library/jesd204/tb/tb_lfsr_input.sv | 95 ++++ library/jesd204/tb/tb_link_layer_fec.sv | 420 ++++++++++++++++++ 23 files changed, 1710 insertions(+), 44 deletions(-) create mode 100755 library/jesd204/jesd204_common/lfsr_input.sv create mode 100755 library/jesd204/jesd204_rx/jesd204_fec_decode.sv create mode 100755 library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv create mode 100755 library/jesd204/jesd204_tx/jesd204_fec_encode.sv create mode 100755 library/jesd204/tb/sim_jesd204_fec.sh create mode 100755 library/jesd204/tb/sim_jesd204_fec_encode.sh create mode 100755 library/jesd204/tb/sim_lfsr_input.sh create mode 100755 library/jesd204/tb/sim_link_layer_fec.sh create mode 100755 library/jesd204/tb/tb_jesd204_fec.sv create mode 100755 library/jesd204/tb/tb_jesd204_fec_encode.v create mode 100755 library/jesd204/tb/tb_lfsr_input.sv create mode 100755 library/jesd204/tb/tb_link_layer_fec.sv diff --git a/library/jesd204/axi_jesd204_common/jesd204_up_common.v b/library/jesd204/axi_jesd204_common/jesd204_up_common.v index fe22bcb7943..896ffff8f5b 100755 --- a/library/jesd204/axi_jesd204_common/jesd204_up_common.v +++ b/library/jesd204/axi_jesd204_common/jesd204_up_common.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2016-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2016-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -54,6 +54,7 @@ module jesd204_up_common #( output reg [7:0] core_cfg_octets_per_frame = 'h00, output reg core_cfg_disable_scrambler = 'h00, output reg core_cfg_disable_char_replacement = 'h00, + output reg [1:0] core_cfg_header_mode = 'h00, output reg [EXTRA_CFG_WIDTH-1:0] core_extra_cfg = 'h00, output reg [DEV_EXTRA_CFG_WIDTH-1:0] device_extra_cfg = 'h00, @@ -75,6 +76,7 @@ module jesd204_up_common #( reg [NUM_LANES-1:0] up_cfg_lanes_disable = {NUM_LANES{1'b0}}; reg [NUM_LINKS-1:0] up_cfg_links_disable = {NUM_LINKS{1'b0}}; reg up_cfg_disable_char_replacement = 1'b0; + reg [1:0] up_cfg_header_mode = 1'b0; reg up_cfg_disable_scrambler = 1'b0; /* Reset for the register map */ @@ -164,6 +166,7 @@ module jesd204_up_common #( core_cfg_links_disable <= up_cfg_links_disable; core_cfg_disable_scrambler <= up_cfg_disable_scrambler; core_cfg_disable_char_replacement <= up_cfg_disable_char_replacement; + core_cfg_header_mode <= up_cfg_header_mode; core_extra_cfg <= up_extra_cfg; end end @@ -291,7 +294,8 @@ module jesd204_up_common #( /* 00-09 */ up_cfg_octets_per_multiframe }; 12'h85: up_rdata = { - /* 02-31 */ 30'h00, /* Reserved for future additions */ + /* 04-31 */ 30'h00, /* Reserved for future additions */ + /* 03-02 */ up_cfg_header_mode, /* 0 - CRC12 ; 1 - CRC3; 2 - FEC; 3 - CMD */ /* 01 */ up_cfg_disable_char_replacement, /* Disable character replacement */ /* 00 */ up_cfg_disable_scrambler /* Disable scrambler */ }; @@ -335,6 +339,7 @@ module jesd204_up_common #( up_cfg_beats_per_multiframe <= 'h00; up_cfg_disable_char_replacement <= 1'b0; + up_cfg_header_mode <= 2'b0; up_cfg_disable_scrambler <= 1'b0; end else if (up_wreq == 1'b1) begin case (up_waddr) @@ -364,6 +369,7 @@ module jesd204_up_common #( {DATA_PATH_WIDTH_LOG2{1'b1}}}; end 12'h085: begin + up_cfg_header_mode <= up_wdata[3:2]; up_cfg_disable_char_replacement <= up_wdata[1]; up_cfg_disable_scrambler <= up_wdata[0]; end diff --git a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v index 33ab3424fe4..07f404c09b1 100755 --- a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v +++ b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2016-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2016-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -53,6 +53,7 @@ module axi_jesd204_rx #( output [7:0] core_cfg_octets_per_frame, output core_cfg_disable_scrambler, output core_cfg_disable_char_replacement, + output [1:0] core_cfg_header_mode, output [7:0] core_cfg_frame_align_err_threshold, output [9:0] device_cfg_octets_per_multiframe, @@ -73,7 +74,7 @@ module axi_jesd204_rx #( input core_event_frame_alignment_error, input core_event_unexpected_lane_state_error, - output [6:0] core_ctrl_err_statistics_mask, + output [8:0] core_ctrl_err_statistics_mask, output core_ctrl_err_statistics_reset, input [32*NUM_LANES-1:0] core_status_err_statistics_cnt, @@ -209,6 +210,7 @@ module axi_jesd204_rx #( .core_cfg_links_disable(core_cfg_links_disable), .core_cfg_disable_scrambler(core_cfg_disable_scrambler), .core_cfg_disable_char_replacement(core_cfg_disable_char_replacement), + .core_cfg_header_mode(core_cfg_header_mode), .up_extra_cfg({ /* 00-07 */ up_cfg_frame_align_err_threshold diff --git a/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v b/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v index f6cdc2a79bb..5457d662bbe 100755 --- a/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v +++ b/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v @@ -37,7 +37,7 @@ module jesd204_up_rx #( input [8*NUM_LANES-1:0] core_status_lane_frame_align_err_cnt, input [32*NUM_LANES-1:0] core_status_err_statistics_cnt, - output [6:0] core_ctrl_err_statistics_mask, + output [8:0] core_ctrl_err_statistics_mask, output core_ctrl_err_statistics_reset, input up_cfg_is_writeable, @@ -57,7 +57,7 @@ module jesd204_up_rx #( wire [32*NUM_LANES-1:0] up_status_err_statistics_cnt; reg up_ctrl_err_statistics_reset = 0; - reg [6:0] up_ctrl_err_statistics_mask = 7'h0; + reg [8:0] up_ctrl_err_statistics_mask = 9'h0; sync_data #( .NUM_OF_BITS(2+NUM_LANES*(3+2+32+8)) @@ -80,7 +80,7 @@ module jesd204_up_rx #( })); sync_data #( - .NUM_OF_BITS(8) + .NUM_OF_BITS(10) ) i_cdc_cfg ( .in_clk(up_clk), .in_data({ @@ -108,9 +108,9 @@ module jesd204_up_rx #( /* 02-09 */ up_cfg_buffer_delay, /* Buffer release delay */ /* 00-01 */ 2'b00 /* Data path width alignment */ }; - 12'h91: up_rdata = { - /* 15-31 */ 17'h00, /* Reserved for future additions */ - /* 08-14 */ up_ctrl_err_statistics_mask, + 12'h91: up_rdata <= { + /* 17-31 */ 15'h00, /* Reserved for future additions */ + /* 08-16 */ up_ctrl_err_statistics_mask, /* 01-07 */ 7'h0, /* 00 */ up_ctrl_err_statistics_reset }; @@ -142,7 +142,7 @@ module jesd204_up_rx #( if (up_reset == 1'b1) begin up_cfg_buffer_early_release <= 1'b0; up_cfg_buffer_delay <= 'h00; - up_ctrl_err_statistics_mask <= 7'h0; + up_ctrl_err_statistics_mask <= 9'h0; up_ctrl_err_statistics_reset <= 1'b0; up_cfg_frame_align_err_threshold <= 8'd4; end else if (up_wreq == 1'b1 && up_cfg_is_writeable == 1'b1) begin @@ -156,7 +156,7 @@ module jesd204_up_rx #( end else if (up_wreq == 1'b1) begin case (up_waddr) 12'h91: begin - up_ctrl_err_statistics_mask <= up_wdata[14:8]; + up_ctrl_err_statistics_mask <= up_wdata[16:8]; up_ctrl_err_statistics_reset <= up_wdata[0]; end 12'h92: begin diff --git a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v index fd201f10e48..c6e83f4ed3c 100755 --- a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v +++ b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2016-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2016-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -56,6 +56,7 @@ module axi_jesd204_tx #( output core_cfg_skip_ilas, output [7:0] core_cfg_mframes_per_ilas, output core_cfg_disable_char_replacement, + output [1:0] core_cfg_header_mode, output core_cfg_disable_scrambler, output [9:0] device_cfg_octets_per_multiframe, @@ -187,6 +188,7 @@ module axi_jesd204_tx #( .core_cfg_links_disable(core_cfg_links_disable), .core_cfg_disable_scrambler(core_cfg_disable_scrambler), .core_cfg_disable_char_replacement(core_cfg_disable_char_replacement), + .core_cfg_header_mode(core_cfg_header_mode), .up_extra_cfg({ /* 10 */ up_cfg_continuous_cgs, diff --git a/library/jesd204/jesd204_common/lfsr_input.sv b/library/jesd204/jesd204_common/lfsr_input.sv new file mode 100755 index 00000000000..da13af0e2a7 --- /dev/null +++ b/library/jesd204/jesd204_common/lfsr_input.sv @@ -0,0 +1,129 @@ +// +// The ADI JESD204 Core is released under the following license, which is +// different than all other HDL cores in this repository. +// +// Please read this, and understand the freedoms and responsibilities you have +// by using this source code/core. +// +// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. +// +// This core is free software, you can use run, copy, study, change, ask +// questions about and improve this core. Distribution of source, or resulting +// binaries (including those inside an FPGA or ASIC) require you to release the +// source of the entire project (excluding the system libraries provide by the +// tools/compiler/FPGA vendor). These are the terms of the GNU General Public +// License version 2 as published by the Free Software Foundation. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License version 2 +// along with this source code, and binary. If not, see +// . +// +// Commercial licenses (with commercial support) of this JESD204 core are also +// available under terms different than the General Public License. (e.g. they +// do not require you to accompany any image (FPGA or ASIC) using the JESD204 +// core with any corresponding source code.) For these alternate terms you must +// purchase a license from Analog Devices Technology Licensing Office. Users +// interested in such a license should contact jesd204-licensing@analog.com for +// more information. This commercial license is sub-licensable (if you purchase +// chips from Analog Devices, incorporate them into your PCB level product, and +// purchase a JESD204 license, end users of your product will also have a +// license to use this core in a commercial setting without releasing their +// source code). +// +// In addition, we kindly ask you to acknowledge ADI in any program, application +// or publication in which you use this JESD204 HDL core. (You are not required +// to do so; it is up to your common sense to decide whether you want to comply +// with this request or not.) For general publications, we suggest referencing : +// “The design and implementation of the JESD204 HDL Core used in this project +// is copyright © 2016-2017, Analog Devices, Inc.” +// + + +`timescale 1ns / 100ps +`default_nettype none + +// LFSR with input +module lfsr_input #( + parameter LFSR_WIDTH = 32, + parameter [LFSR_WIDTH:1] RESET_VAL = {LFSR_WIDTH{1'b0}}, + // LFSR_POLYNOMIAL[0] must be 1 and is omitted + parameter [LFSR_WIDTH:1] LFSR_POLYNOMIAL = {LFSR_WIDTH{1'b0}}, + parameter MAX_SHIFT_CNT = 64 +)( + // One cycle after shift_en = 1, + // data_out[shift_cnt:0] contains the next shift_cnt + 1 output bits + // data_out[MAX_SHIFT_CNT-1:shift_cnt+1] is undefined + output logic [MAX_SHIFT_CNT-1:0] data_out, + // Value of the shift register updated one cycle after shift_en is asserted + output logic [LFSR_WIDTH:1] shift_reg, + // Value of the shift register if shift_en is asserted for each value of shift_cnt from 1 to MAX_SHIFT_CNT + output logic [LFSR_WIDTH:1] shift_reg_next[MAX_SHIFT_CNT-1:0], + input wire clk, + input wire rst, + input wire shift_reg_reset, + input wire shift_en, + // Number of bits to shift - 1 + input wire [$clog2(MAX_SHIFT_CNT)-1:0] shift_cnt, + input wire [MAX_SHIFT_CNT-1:0] data_in +); + + function automatic [LFSR_WIDTH:1] lfsr_galois_next(input [LFSR_WIDTH:1] cur, input next_data_in); + int ii; + reg next_msb; + next_msb = cur[1] ^ next_data_in; + lfsr_galois_next[LFSR_WIDTH] = next_msb; + for(ii = LFSR_WIDTH-1; ii > 0; ii=ii-1) begin : shift_reg_gen + lfsr_galois_next[ii] = cur[ii+1] ^ (next_msb & LFSR_POLYNOMIAL[ii]); + end + endfunction + + wire [MAX_SHIFT_CNT-1:0] data_out_next; + reg [LFSR_WIDTH:1] shift_reg_in_start; + wire [LFSR_WIDTH:1] shift_reg_in_next[MAX_SHIFT_CNT-1:0]; + genvar jj; + + + + // Generate shift register values for each number of shifts + for(jj = 0; jj < MAX_SHIFT_CNT; jj = jj + 1) begin : shift_gen + // Shift register input is output of previous shift register value + if(jj == 0) begin : zero_gen + assign shift_reg_in_next[jj] = shift_reg_in_start; + end else begin : non_zero_gen + assign shift_reg_in_next[jj] = shift_reg_next[jj-1]; + end + + // Output bit is the LSb of the shift register + assign data_out_next[jj] = shift_reg_in_next[jj][1]; + + assign shift_reg_next[jj] = lfsr_galois_next(shift_reg_in_next[jj], data_in[jj]); + end + + always @(posedge clk) begin + if(shift_reg_reset || rst) begin + shift_reg_in_start <= RESET_VAL; + end else if(shift_en) begin + shift_reg_in_start <= shift_reg_next[shift_cnt]; + end + end + + always @(posedge clk) begin + if(rst) begin + shift_reg <= RESET_VAL; + end else begin + if(shift_en) begin + shift_reg <= shift_reg_next[shift_cnt]; + data_out <= data_out_next; + end else if(shift_reg_reset) begin + shift_reg <= RESET_VAL; + end + end + end + +endmodule + +`default_nettype wire diff --git a/library/jesd204/jesd204_rx/jesd204_fec_decode.sv b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv new file mode 100755 index 00000000000..9e1c5841849 --- /dev/null +++ b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv @@ -0,0 +1,347 @@ +// +// The ADI JESD204 Core is released under the following license, which is +// different than all other HDL cores in this repository. +// +// Please read this, and understand the freedoms and responsibilities you have +// by using this source code/core. +// +// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. +// +// This core is free software, you can use run, copy, study, change, ask +// questions about and improve this core. Distribution of source, or resulting +// binaries (including those inside an FPGA or ASIC) require you to release the +// source of the entire project (excluding the system libraries provide by the +// tools/compiler/FPGA vendor). These are the terms of the GNU General Public +// License version 2 as published by the Free Software Foundation. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License version 2 +// along with this source code, and binary. If not, see +// . +// +// Commercial licenses (with commercial support) of this JESD204 core are also +// available under terms different than the General Public License. (e.g. they +// do not require you to accompany any image (FPGA or ASIC) using the JESD204 +// core with any corresponding source code.) For these alternate terms you must +// purchase a license from Analog Devices Technology Licensing Office. Users +// interested in such a license should contact jesd204-licensing@analog.com for +// more information. This commercial license is sub-licensable (if you purchase +// chips from Analog Devices, incorporate them into your PCB level product, and +// purchase a JESD204 license, end users of your product will also have a +// license to use this core in a commercial setting without releasing their +// source code). +// +// In addition, we kindly ask you to acknowledge ADI in any program, application +// or publication in which you use this JESD204 HDL core. (You are not required +// to do so; it is up to your common sense to decide whether you want to comply +// with this request or not.) For general publications, we suggest referencing : +// “The design and implementation of the JESD204 HDL Core used in this project +// is copyright © 2016-2017, Analog Devices, Inc.” +// + + +`timescale 1ns / 100ps + +// JESD204C FEC decoder +module jesd204_fec_decode #( + parameter DATA_WIDTH = 64 +)( + output logic [DATA_WIDTH-1:0] data_out, + output logic data_out_valid, + output logic trapped_error_flag, + output logic untrapped_error_flag, + input wire clk, + input wire rst, + input wire eomb, + input wire fec_in_valid, + input wire [25:0] fec_in, + input wire [DATA_WIDTH-1:0] data_in +); + + localparam DATA_WIDTH_WIDTH=$clog2(DATA_WIDTH); + localparam FEC_WIDTH = 26; + localparam FEC_WIDTH_WIDTH = $clog2(FEC_WIDTH); + localparam [FEC_WIDTH:1] RESET_VAL = {FEC_WIDTH{1'b0}}; + localparam BLOCK_LENGTH = 2048; + localparam MAX_BURST_LEN = 9; // Max correctable error burst length + localparam BUFFER_NUM_BLOCKS = 2; + localparam BLOCK_CYCLE_CNT = BLOCK_LENGTH/DATA_WIDTH; + localparam BUFFER_DEPTH = BLOCK_CYCLE_CNT*BUFFER_NUM_BLOCKS; + localparam BUFFER_ADDR_WIDTH = $clog2(BUFFER_DEPTH); + localparam NUM_BLOCKS_WIDTH = $clog2(BUFFER_NUM_BLOCKS); + localparam CYCLE_WIDTH = $clog2(BLOCK_CYCLE_CNT); + + logic [FEC_WIDTH-1:0] fec_in_reversed; + logic [FEC_WIDTH:1] data_in_syndrome; + logic [FEC_WIDTH:1] data_in_syndrome_saved; + logic [FEC_WIDTH:1] codeword_syndrome; + logic [FEC_WIDTH:1] error_syndrome_next[DATA_WIDTH-1:0]; + logic [FEC_WIDTH:1] error_syndrome_next_d[DATA_WIDTH-1:0]; + logic [DATA_WIDTH+MAX_BURST_LEN-1:0] error_syndrome_next_shifted[DATA_WIDTH-1:0]; + logic [DATA_WIDTH+MAX_BURST_LEN-1:0] error_bits; + logic [MAX_BURST_LEN-1:0] error_bits_prev; + logic [NUM_BLOCKS_WIDTH-1:0] buf_wr_block; + logic [NUM_BLOCKS_WIDTH-1:0] buf_rd_block; + logic [CYCLE_WIDTH-1:0] buf_wr_cycle; + logic [CYCLE_WIDTH-1:0] buf_rd_cycle; + logic buf_wr_en; + logic [BUFFER_ADDR_WIDTH-1:0] buf_wr_addr; + logic [BUFFER_ADDR_WIDTH-1:0] buf_rd_addr; + logic [DATA_WIDTH-1:0] buf_wr_data; + logic [DATA_WIDTH-1:0] buf_rd_data; + logic [DATA_WIDTH-1:0] buf_rd_data_d; + logic [3:1] eomb_d; + logic data_in_en; + logic fec_in_en; + logic data_out_en; + logic [2:1] data_out_en_d; + logic data_in_syndrome_avail; + logic [DATA_WIDTH-1:0] error_trapped; + logic [DATA_WIDTH-1:0] error; + logic any_error_trapped; + logic any_error; + logic trapped_error_sticky; + logic error_sticky; + logic trapped_error_sticky_comb; + logic error_sticky_comb; + int jj; + genvar ii; + + // Reverse order of FEC bits so that bit 25 is shifted in first + for(ii = 0; ii < 26; ii = ii + 1) begin : fec_reverse_gen + assign fec_in_reversed[ii] = fec_in[25-ii]; + end + + // Data input enabled after first EoMB + // FEC input enabled after next EoMB + // Data output enabled after next EoMB + always @(posedge clk) begin + if(rst) begin + data_in_en <= 1'b0; + fec_in_en <= 1'b0; + data_out_en <= 1'b0; + end else begin + if(eomb) begin + data_in_en <= 1'b1; + fec_in_en <= data_in_en; + data_out_en <= fec_in_en; + end + end + end + + // Data buffer + ad_mem_dist #( + .RAM_WIDTH (DATA_WIDTH), + .RAM_ADDR_BITS (BUFFER_ADDR_WIDTH) + ) data_buffer ( + .rd_data (buf_rd_data), + .clk (clk), + .wr_en (buf_wr_en), + .wr_addr (buf_wr_addr), + .wr_data (buf_wr_data), + .rd_addr (buf_rd_addr) + ); + + assign buf_wr_en = data_in_en; + assign buf_wr_data = data_in; + assign buf_wr_addr = {buf_wr_block, buf_wr_cycle}; + assign buf_rd_addr = {buf_rd_block, buf_rd_cycle}; + + // Keep track of read and write block counts and block cycle counts + // in case link goes down then up, causing partial blocks + always @(posedge clk) begin + if(rst) begin + buf_wr_block <= '0; + buf_wr_cycle <= '0; + end else begin + if(data_in_en) begin + if(eomb) begin + if(buf_wr_block == (BUFFER_NUM_BLOCKS-1)) begin + buf_wr_block <= '0; + end else begin + buf_wr_block <= buf_wr_block + 1'b1; + end + + buf_wr_cycle <= '0; + end else begin + buf_wr_cycle <= buf_wr_cycle + 1'b1; + end + end + end + end + + always @(posedge clk) begin + if(rst) begin + buf_rd_block <= '0; + buf_rd_cycle <= '0; + end else begin + if(data_out_en) begin + if(eomb) begin + if(buf_rd_block == (BUFFER_NUM_BLOCKS-1)) begin + buf_rd_block <= '0; + end else begin + buf_rd_block <= buf_rd_block + 1'b1; + end + + buf_rd_cycle <= '0; + end else begin + buf_rd_cycle <= buf_rd_cycle + 1'b1; + end + end + end + end + + // Input data syndrome computation + jesd204_rx_fec_lfsr #( + .MAX_SHIFT_CNT (DATA_WIDTH) + ) data_in_lfsr ( + .data_out (), + .shift_reg (data_in_syndrome), + .shift_reg_next (), + .clk (clk), + .rst (rst), + .load_en (eomb), + .load_data ('0), + .shift_en (data_in_en), + .shift_cnt (DATA_WIDTH_WIDTH'(DATA_WIDTH-1)), + .data_in (data_in) + ); + + // Save codeword_lfsr after the input data syndrome is computed + always @(posedge clk) begin + if(rst) begin + data_in_syndrome_avail <= 1'b0; + end else begin + data_in_syndrome_avail <= data_in_en && eomb_d[1]; + end + end + + always @(posedge clk) begin + if(eomb_d[1]) begin + data_in_syndrome_saved <= data_in_syndrome; + end + end + + // Codeword syndrome computation using received FEC + jesd204_rx_fec_lfsr #( + .MAX_SHIFT_CNT (FEC_WIDTH) + ) codeword_lfsr ( + .data_out (), + .shift_reg (codeword_syndrome), + .shift_reg_next (), + .clk (clk), + .rst (rst), + .load_en (data_in_syndrome_avail), + .load_data (data_in_syndrome_saved), + .shift_en (fec_in_valid), + .shift_cnt (FEC_WIDTH_WIDTH'(FEC_WIDTH-1)), + .data_in (fec_in_reversed) + ); + + // Error syndrome computation + jesd204_rx_fec_lfsr #( + .MAX_SHIFT_CNT (DATA_WIDTH) + ) error_lfsr ( + .data_out (), + .shift_reg (), + .shift_reg_next (error_syndrome_next), + .clk (clk), + .rst (rst), + .load_en (eomb), + .load_data (codeword_syndrome), + .shift_en (data_out_en), + .shift_cnt (DATA_WIDTH_WIDTH'(DATA_WIDTH-1)), + .data_in ({DATA_WIDTH{1'b0}}) + ); + + always_ff @(posedge clk) begin + error_syndrome_next_d <= error_syndrome_next; + buf_rd_data_d <= buf_rd_data; + end + + // Error is trapped if the MSb of the syndrome is 1 and bits 16:0 of the syndrome are 0 + // MSb (bit S25) of the syndrome is in the rightmost bit of error_syndrome_next_d[ii] + for(ii = 0; ii < DATA_WIDTH; ii = ii + 1) begin : error_trap_gen + assign error_trapped[ii] = error_syndrome_next_d[ii][1] && ~|(error_syndrome_next_d[ii][26:10]); + assign error[ii] = error_syndrome_next_d[ii][1]; + end + + always @(posedge clk) begin + any_error_trapped <= |error_trapped; + any_error <= |error; + end + + // Shift syndromes to align with data + for(ii = 0; ii < DATA_WIDTH; ii = ii + 1) begin : syndrome_shift_gen + assign error_syndrome_next_shifted[ii] = {error_syndrome_next_d[ii][MAX_BURST_LEN:1], {(ii+1){1'b0}}}; + end + + // Determine error bits by checking for trapped error + always @(*) begin + error_bits = '0; + for(jj = 0; jj < DATA_WIDTH; jj = jj + 1'b1) begin : correct_gen + if(error_trapped[jj]) begin + error_bits = error_bits ^ error_syndrome_next_shifted[jj]; + end + end + end + + // Save remaining error bits to use next cycle + always @(posedge clk) begin + if(eomb_d[1]) begin + error_bits_prev <= '0; + end else begin + error_bits_prev <= error_bits[DATA_WIDTH+:MAX_BURST_LEN]; + end + end + + // Correct data by XORing with FEC syndrome + // Output corrected data + always_ff @(posedge clk) begin + data_out <= buf_rd_data_d ^ error_bits[DATA_WIDTH-1:0] ^ error_bits_prev; + data_out_valid <= data_out_en_d[1]; + end + + // Flag trapped and untrapped errors, once per-block + assign trapped_error_sticky_comb = (eomb_d[3] ? 1'b0 : trapped_error_sticky) || any_error_trapped; + assign error_sticky_comb = (eomb_d[3] ? 1'b0 : error_sticky) || any_error; + + always @(posedge clk) begin + if(rst) begin + trapped_error_flag <= 1'b0; + untrapped_error_flag <= 1'b0; + trapped_error_sticky <= 1'b0; + error_sticky <= 1'b0; + end else begin + trapped_error_flag <= 1'b0; + untrapped_error_flag <= 1'b0; + + if(data_out_en_d[2]) begin + trapped_error_sticky <= trapped_error_sticky_comb; + error_sticky <= error_sticky_comb; + if(eomb_d[2]) begin + trapped_error_flag <= trapped_error_sticky_comb; + untrapped_error_flag <= !trapped_error_sticky_comb && error_sticky_comb; + end + end else begin + trapped_error_sticky <= 1'b0; + error_sticky <= 1'b0; + end + end + end + + // Delay registers + always @(posedge clk) begin + if(rst) begin + eomb_d <= 3'b0; + data_out_en_d <= 2'b0; + end else begin + eomb_d <= {eomb_d[2:1], eomb}; + data_out_en_d <= {data_out_en_d[1], data_out_en}; + end + end + +endmodule diff --git a/library/jesd204/jesd204_rx/jesd204_rx.v b/library/jesd204/jesd204_rx/jesd204_rx.v index d4d18153e74..31c88b174f6 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx.v +++ b/library/jesd204/jesd204_rx/jesd204_rx.v @@ -18,6 +18,7 @@ module jesd204_rx #( parameter ENABLE_FRAME_ALIGN_CHECK = 1, parameter ENABLE_FRAME_ALIGN_ERR_RESET = 0, parameter ENABLE_CHAR_REPLACE = 0, + parameter ENABLE_FEC = 0, parameter ASYNC_CLK = 1, parameter TPL_DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4 ) ( @@ -59,6 +60,7 @@ module jesd204_rx #( input [9:0] cfg_octets_per_multiframe, input [7:0] cfg_octets_per_frame, input cfg_disable_scrambler, + input [1:0] cfg_header_mode, input cfg_disable_char_replacement, input [7:0] cfg_frame_align_err_threshold, @@ -72,7 +74,7 @@ module jesd204_rx #( input [7:0] device_cfg_buffer_delay, input ctrl_err_statistics_reset, - input [6:0] ctrl_err_statistics_mask, + input [8:0] ctrl_err_statistics_mask, output [32*NUM_LANES-1:0] status_err_statistics_cnt, @@ -501,6 +503,7 @@ module jesd204_rx #( jesd204_rx_lane_64b #( .ELASTIC_BUFFER_SIZE(ELASTIC_BUFFER_SIZE), + .ENABLE_FEC(ENABLE_FEC), .TPL_DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH), .ASYNC_CLK(ASYNC_CLK) ) i_lane ( @@ -515,7 +518,7 @@ module jesd204_rx #( .phy_block_sync(phy_block_sync_r[i]), .cfg_disable_scrambler(cfg_disable_scrambler), - .cfg_header_mode(2'b0), + .cfg_header_mode(cfg_header_mode), .cfg_rx_thresh_emb_err(5'd8), .cfg_beats_per_multiframe(cfg_beats_per_multiframe), @@ -529,7 +532,7 @@ module jesd204_rx #( .emb_lock(emb_lock[i]), .ctrl_err_statistics_reset(ctrl_err_statistics_reset), - .ctrl_err_statistics_mask(ctrl_err_statistics_mask[6:3]), + .ctrl_err_statistics_mask(ctrl_err_statistics_mask[8:3]), .status_err_statistics_cnt(status_err_statistics_cnt[32*i+31:32*i]), .status_lane_emb_state(status_lane_emb_state[3*i+2:3*i]), diff --git a/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv b/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv new file mode 100755 index 00000000000..8dead64bfef --- /dev/null +++ b/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv @@ -0,0 +1,145 @@ +// +// The ADI JESD204 Core is released under the following license, which is +// different than all other HDL cores in this repository. +// +// Please read this, and understand the freedoms and responsibilities you have +// by using this source code/core. +// +// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. +// +// This core is free software, you can use run, copy, study, change, ask +// questions about and improve this core. Distribution of source, or resulting +// binaries (including those inside an FPGA or ASIC) require you to release the +// source of the entire project (excluding the system libraries provide by the +// tools/compiler/FPGA vendor). These are the terms of the GNU General Public +// License version 2 as published by the Free Software Foundation. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License version 2 +// along with this source code, and binary. If not, see +// . +// +// Commercial licenses (with commercial support) of this JESD204 core are also +// available under terms different than the General Public License. (e.g. they +// do not require you to accompany any image (FPGA or ASIC) using the JESD204 +// core with any corresponding source code.) For these alternate terms you must +// purchase a license from Analog Devices Technology Licensing Office. Users +// interested in such a license should contact jesd204-licensing@analog.com for +// more information. This commercial license is sub-licensable (if you purchase +// chips from Analog Devices, incorporate them into your PCB level product, and +// purchase a JESD204 license, end users of your product will also have a +// license to use this core in a commercial setting without releasing their +// source code). +// +// In addition, we kindly ask you to acknowledge ADI in any program, application +// or publication in which you use this JESD204 HDL core. (You are not required +// to do so; it is up to your common sense to decide whether you want to comply +// with this request or not.) For general publications, we suggest referencing : +// “The design and implementation of the JESD204 HDL Core used in this project +// is copyright © 2016-2017, Analog Devices, Inc.” +// + + +`timescale 1ns / 100ps + +// JESD204C RX FEC DECODER LFSR +module jesd204_rx_fec_lfsr #( + localparam LFSR_WIDTH = 26, + parameter MAX_SHIFT_CNT = 64 +)( + // One cycle after shift_en = 1, + // data_out[shift_cnt:0] contains the next shift_cnt + 1 output bits + // data_out[MAX_SHIFT_CNT-1:shift_cnt+1] is undefined + output logic [MAX_SHIFT_CNT-1:0] data_out, + // Value of the shift register updated one cycle after shift_en is asserted + output logic [LFSR_WIDTH:1] shift_reg, + // Value of the shift register if shift_en is asserted for each value of shift_cnt from 1 to MAX_SHIFT_CNT + output logic [LFSR_WIDTH:1] shift_reg_next[MAX_SHIFT_CNT-1:0], + input wire clk, + input wire rst, + input wire load_en, + input wire [LFSR_WIDTH:1] load_data, + input wire shift_en, + // Number of bits to shift - 1 + input wire [$clog2(MAX_SHIFT_CNT)-1:0] shift_cnt, + input wire [MAX_SHIFT_CNT-1:0] data_in +); + + localparam [LFSR_WIDTH:1] RESET_VAL = {LFSR_WIDTH{1'b0}}; + + // 𝑥^26 + 𝑥^21 + 𝑥^17 + 𝑥^9 + 𝑥^4 + 1 + // 100001000100000001000010001 + // Remove the MSb (x^26) term because it corresponds to one shift past the end of the LFSR, + // and represents feedback from the x^26 term to the other taps + // 0000 1000 1000 0000 1000 0100 01 + // Reverse the order of the taps because the LSb of the LFSR contains the MSb of the FEC data + // 10 0010 0001 0000 0001 0001 0000 + localparam [LFSR_WIDTH:1] FEC_POLYNOMIAL_1 = 26'h2210110; + + // 𝑥^24 + 𝑥^21 + 𝑥^19 + 𝑥^18 + 𝑥^17 + 𝑥^9 + 𝑥^7 + 𝑥^4 + 𝑥^2 + 𝑥 + 1 + // 001001011100000001010010111 + // Remove the MSb (x^26) term because it corresponds to one shift past the end of the LFSR + // 0100 1011 1000 0000 1010 0101 11 + // Reverse the order of the taps because the LSb of the LFSR contains the MSb of the FEC data + // 11 1010 0101 0000 0001 1101 0010 + localparam [LFSR_WIDTH:1] FEC_POLYNOMIAL_2 = 26'h3A501D2; + + function automatic [LFSR_WIDTH:1] fec_decode_galois_next(input [LFSR_WIDTH:1] cur, input next_data_in); + int ii; + reg x_26 = cur[1]; + fec_decode_galois_next[LFSR_WIDTH] = next_data_in ^ x_26; + for(ii = LFSR_WIDTH-1; ii > 0; ii=ii-1) begin : shift_reg_gen + fec_decode_galois_next[ii] = cur[ii+1] ^ (x_26 & FEC_POLYNOMIAL_1[ii]) ^ (next_data_in & FEC_POLYNOMIAL_2[ii]); + end + endfunction + + logic [MAX_SHIFT_CNT-1:0] data_out_next; + logic [LFSR_WIDTH:1] shift_reg_in_start; + logic [LFSR_WIDTH:1] shift_reg_in_next[MAX_SHIFT_CNT-1:0]; + genvar jj; + + // Generate shift register values for each number of shifts + for(jj = 0; jj < MAX_SHIFT_CNT; jj = jj + 1) begin : shift_gen + if(jj == 0) begin : zero_gen + assign shift_reg_in_next[jj] = shift_reg_in_start; + end else begin : non_zero_gen + assign shift_reg_in_next[jj] = shift_reg_next[jj-1]; + end + + // Output bit is the LSb of the shift register + assign data_out_next[jj] = shift_reg_in_next[jj][1]; + + assign shift_reg_next[jj] = fec_decode_galois_next(shift_reg_in_next[jj], data_in[jj]); + end + + // Shift register input is output of previous shift register value, + // or load value if load enabled + always @(posedge clk) begin + if(rst) begin + shift_reg_in_start <= RESET_VAL; + end else begin + if(load_en) begin + shift_reg_in_start <= load_data; + end else if(shift_en) begin + shift_reg_in_start <= shift_reg_next[shift_cnt]; + end + end + end + + always @(posedge clk) begin + if(rst) begin + shift_reg <= RESET_VAL; + end else begin + if(shift_en) begin + shift_reg <= shift_reg_next[shift_cnt]; + data_out <= data_out_next; + end else if(load_en) begin + shift_reg <= load_data; + end + end + end + +endmodule diff --git a/library/jesd204/jesd204_rx/jesd204_rx_header.v b/library/jesd204/jesd204_rx/jesd204_rx_header.v index 14e34e32a8b..4a3bab5ab10 100644 --- a/library/jesd204/jesd204_rx/jesd204_rx_header.v +++ b/library/jesd204/jesd204_rx/jesd204_rx_header.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2020, 2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2020, 2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -22,6 +22,7 @@ module jesd204_rx_header ( output valid_eomb, output valid_eoemb, + output reg valid_fec, // Received header data qualified by valid_eomb output [11:0] crc12, output [2:0] crc3, @@ -81,7 +82,7 @@ module jesd204_rx_header ( cfg_header_mode == 1 ? {12'b0,cmd1} : cfg_header_mode == 3 ? cmd3 : 'b0; - assign fec = {sync_word[31:10],sync_word[8:5]}; + assign fec = {sync_word[26:5],sync_word[3:0]}; assign eomb = sync_word[4:0] == 5'b00001; assign eoemb = sync_word[9] & eomb; @@ -139,11 +140,20 @@ module jesd204_rx_header ( assign invalid_eoemb = (sh_count == 0 && ~eoemb); assign invalid_eomb = (sh_count[4:0] == 0 && ~eomb); - assign valid_eomb = next_state[BIT_EMB_LOCK] && eomb; - assign valid_eoemb = next_state[BIT_EMB_LOCK] && eoemb; + assign valid_eomb = next_state[BIT_EMB_LOCK] && (sh_count == 0) && eomb; + assign valid_eoemb = next_state[BIT_EMB_LOCK] && (sh_count == 0) && eoemb; assign invalid_sequence = (invalid_eoemb || invalid_eomb); +// FEC signal is available before EOMB +always @(posedge clk) begin + if (reset == 1'b1) begin + valid_fec <= 1'b0; + end else begin + valid_fec <= next_state[BIT_EMB_LOCK] && (sh_count[4:0] == 26); + end +end + always @(posedge clk) begin if (reset == 1'b1) begin state <= STATE_EMB_INIT; diff --git a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v index b44f4632b35..cbb248d72ae 100644 --- a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v +++ b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v @@ -9,6 +9,7 @@ module jesd204_rx_lane_64b #( parameter ELASTIC_BUFFER_SIZE = 256, + parameter ENABLE_FEC = 1'b0, parameter TPL_DATA_PATH_WIDTH = 8, parameter ASYNC_CLK = 0 ) ( @@ -37,7 +38,7 @@ module jesd204_rx_lane_64b #( input [7:0] cfg_beats_per_multiframe, input ctrl_err_statistics_reset, - input [3:0] ctrl_err_statistics_mask, + input [5:0] ctrl_err_statistics_mask, output [31:0] status_err_statistics_cnt, output [2:0] status_lane_emb_state, @@ -46,6 +47,7 @@ module jesd204_rx_lane_64b #( reg [11:0] crc12_calculated_prev; + wire [63:0] phy_data_r; wire [63:0] data_descrambled_s; wire [63:0] data_descrambled; wire [63:0] data_descrambled_reordered; @@ -56,12 +58,27 @@ module jesd204_rx_lane_64b #( wire event_unexpected_eomb; wire event_unexpected_eoemb; wire event_crc12_mismatch; + wire event_fec_trapped_error_flag; + wire event_fec_untrapped_error_flag; wire err_cnt_rst; wire [63:0] rx_data_msb_s; wire eomb; wire eoemb; + wire eomb_r; + wire valid_fec; + wire [25:0] fec_received; + wire fec_en; + wire [63:0] fec_data_out; + wire [63:0] scram_data_in; + wire fec_data_out_valid; + wire fec_trapped_error_flag; + wire fec_untrapped_error_flag; + wire buffer_not_ready_next; + wire buffer_ready_next; + reg [2:1] buffer_not_ready_r; + reg [2:1] buffer_ready_r; wire [7:0] sh_count; @@ -80,9 +97,10 @@ module jesd204_rx_lane_64b #( .valid_eomb(eomb), .valid_eoemb(eoemb), + .valid_fec(valid_fec), .crc12(crc12_received), .crc3(), - .fec(), + .fec(fec_received), .cmd(), .sh_count(sh_count), @@ -102,7 +120,7 @@ module jesd204_rx_lane_64b #( always @(posedge clk) begin if (reset == 1'b1) begin crc12_on <= 1'b0; - end else if (eomb) begin + end else if ((cfg_header_mode == 2'd0) && eomb_r) begin crc12_on <= 1'b1; end end @@ -126,14 +144,41 @@ module jesd204_rx_lane_64b #( assign err_cnt_rst = reset || ctrl_err_statistics_reset; + assign fec_en = (cfg_header_mode == 2'd2); + + if(ENABLE_FEC) begin : gen_fec + jesd204_fec_decode #( + .DATA_WIDTH (64) + ) jesd204_fec_decode ( + .data_out (fec_data_out), + .data_out_valid (fec_data_out_valid), + .trapped_error_flag (fec_trapped_error_flag), + .untrapped_error_flag (fec_untrapped_error_flag), + .clk (clk), + .rst (reset), + .eomb (eomb), + .fec_in_valid (valid_fec), + .fec_in (fec_received), + .data_in (phy_data) + ); + + assign scram_data_in = fec_en ? fec_data_out : phy_data; + assign event_fec_trapped_error_flag = fec_en && fec_trapped_error_flag; + assign event_fec_untrapped_error_flag = fec_en && fec_untrapped_error_flag; + end else begin : gen_no_fec + assign scram_data_in = phy_data; + end + error_monitor #( - .EVENT_WIDTH(4), + .EVENT_WIDTH(6), .CNT_WIDTH(32) ) i_error_monitor ( .clk(clk), .reset(err_cnt_rst), .active(1'b1), .error_event({ + event_fec_trapped_error_flag, + event_fec_untrapped_error_flag, event_invalid_header, event_unexpected_eomb, event_unexpected_eoemb, @@ -147,9 +192,9 @@ module jesd204_rx_lane_64b #( .DESCRAMBLE(1) ) i_descrambler ( .clk(clk), - .reset(1'b0), + .reset(reset), .enable(~cfg_disable_scrambler), - .data_in(phy_data), + .data_in(scram_data_in), .data_out(data_descrambled_s)); util_pipeline_stage #( @@ -169,13 +214,33 @@ module jesd204_rx_lane_64b #( // other lanes are not writing in the next half multiblock period stop // writing. // This limits the supported lane skew to half of the multiframe + + assign buffer_not_ready_next = sh_count == {1'b0,cfg_beats_per_multiframe[7:1]} && all_buffer_ready_n; + assign buffer_ready_next = eomb; + always @(posedge clk) begin - if (reset | ~emb_lock) begin - buffer_ready_n <= 1'b1; - end else if (sh_count == {1'b0,cfg_beats_per_multiframe[7:1]} && all_buffer_ready_n) begin + buffer_not_ready_r <= {buffer_not_ready_r[1], buffer_not_ready_next}; + buffer_ready_r <= {buffer_ready_r[1], buffer_ready_next}; + end + + always @(posedge clk) begin + if (reset | ~emb_lock | (fec_en & ~fec_data_out_valid)) begin buffer_ready_n <= 1'b1; - end else if (eoemb) begin - buffer_ready_n <= 1'b0; + end else begin + // FEC data is delayed by 2 cycles + if(fec_en) begin + if(buffer_not_ready_r[2]) begin + buffer_ready_n <= 1'b1; + end else if(buffer_ready_r[2]) begin + buffer_ready_n <= 1'b0; + end + end else begin + if(buffer_not_ready_next) begin + buffer_ready_n <= 1'b1; + end else if(buffer_ready_next) begin + buffer_ready_n <= 1'b0; + end + end end end diff --git a/library/jesd204/jesd204_rx_static_config/jesd204_rx_static_config.v b/library/jesd204/jesd204_rx_static_config/jesd204_rx_static_config.v index 8c721bed9d3..811fe3ab3dd 100755 --- a/library/jesd204/jesd204_rx_static_config/jesd204_rx_static_config.v +++ b/library/jesd204/jesd204_rx_static_config/jesd204_rx_static_config.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2017, 2018, 2020-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2017, 2018, 2020-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -15,6 +15,7 @@ module jesd204_rx_static_config #( parameter SCR = 1, parameter BUFFER_EARLY_RELEASE = 0, parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B + parameter HEADER_MODE = 0, // 0 - CRC12 ; 1 - CRC3; 2 - FEC; 3 - CMD parameter SYSREF_DISABLE = 0, parameter SYSREF_ONE_SHOT = 0, /* Only 4, 8 are supported at the moment for 8b/10b and 8 for 64b */ @@ -29,6 +30,7 @@ module jesd204_rx_static_config #( output [7:0] cfg_octets_per_frame, output cfg_disable_scrambler, output cfg_disable_char_replacement, + output [1:0] cfg_header_mode, output [7:0] cfg_frame_align_err_threshold, output [9:0] device_cfg_octets_per_multiframe, @@ -56,6 +58,7 @@ module jesd204_rx_static_config #( assign cfg_links_disable = {NUM_LINKS{1'b0}}; assign cfg_disable_scrambler = SCR ? 1'b0 : 1'b1; assign cfg_disable_char_replacement = 1'b0; + assign cfg_header_mode = HEADER_MODE; assign cfg_frame_align_err_threshold = 8'd4; endmodule diff --git a/library/jesd204/jesd204_tx/jesd204_fec_encode.sv b/library/jesd204/jesd204_tx/jesd204_fec_encode.sv new file mode 100755 index 00000000000..054d70bf001 --- /dev/null +++ b/library/jesd204/jesd204_tx/jesd204_fec_encode.sv @@ -0,0 +1,95 @@ +// +// The ADI JESD204 Core is released under the following license, which is +// different than all other HDL cores in this repository. +// +// Please read this, and understand the freedoms and responsibilities you have +// by using this source code/core. +// +// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. +// +// This core is free software, you can use run, copy, study, change, ask +// questions about and improve this core. Distribution of source, or resulting +// binaries (including those inside an FPGA or ASIC) require you to release the +// source of the entire project (excluding the system libraries provide by the +// tools/compiler/FPGA vendor). These are the terms of the GNU General Public +// License version 2 as published by the Free Software Foundation. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License version 2 +// along with this source code, and binary. If not, see +// . +// +// Commercial licenses (with commercial support) of this JESD204 core are also +// available under terms different than the General Public License. (e.g. they +// do not require you to accompany any image (FPGA or ASIC) using the JESD204 +// core with any corresponding source code.) For these alternate terms you must +// purchase a license from Analog Devices Technology Licensing Office. Users +// interested in such a license should contact jesd204-licensing@analog.com for +// more information. This commercial license is sub-licensable (if you purchase +// chips from Analog Devices, incorporate them into your PCB level product, and +// purchase a JESD204 license, end users of your product will also have a +// license to use this core in a commercial setting without releasing their +// source code). +// +// In addition, we kindly ask you to acknowledge ADI in any program, application +// or publication in which you use this JESD204 HDL core. (You are not required +// to do so; it is up to your common sense to decide whether you want to comply +// with this request or not.) For general publications, we suggest referencing : +// “The design and implementation of the JESD204 HDL Core used in this project +// is copyright © 2016-2017, Analog Devices, Inc.” +// + + +`timescale 1ns / 100ps + +// JESD204C FEC encoder +module jesd204_fec_encode #( + parameter DATA_WIDTH = 64 +)( + output logic [25:0] fec, + input wire clk, + input wire rst, + input wire shift_en, + input wire eomb, + input wire [DATA_WIDTH-1:0] data_in +); + + localparam [$clog2(DATA_WIDTH)-1:0] SHIFT_CNT = DATA_WIDTH-1; + + // 𝑥^26 + 𝑥^21 + 𝑥^17 + 𝑥^9 + 𝑥^4 + 1 + // 100001000100000001000010001 + // Remove the MSb (x^26) term because it represents the loopback from LSb of the LFSR to the MSb + // 0000 1000 1000 0000 1000 0100 01 + // Reverse the order of the taps because the LSb of the LFSR contains the MSb of the FEC data + // 10 0010 0001 0000 0001 0001 0000 + localparam [26:1] FEC_POLYNOMIAL = 26'h2210110; + + logic [25:0] fec_reversed; + genvar ii; + + // Reverse order of FEC bits so that fec[25:0] matches FEC[25:0] from the JESD204 specification + for(ii = 0; ii < 26; ii = ii + 1) begin : reverse_gen + assign fec[ii] = fec_reversed[25-ii]; + end + + lfsr_input #( + .LFSR_WIDTH (26), + .RESET_VAL ('0), + .LFSR_POLYNOMIAL (FEC_POLYNOMIAL), + .MAX_SHIFT_CNT (DATA_WIDTH) + ) lfsr_input ( + .data_out (), + .shift_reg (fec_reversed), + .shift_reg_next (), + .clk (clk), + .rst (rst), + .shift_en (shift_en), + .shift_reg_reset (eomb), + .shift_cnt (SHIFT_CNT), + .data_in (data_in) + ); + +endmodule diff --git a/library/jesd204/jesd204_tx/jesd204_tx.v b/library/jesd204/jesd204_tx/jesd204_tx.v index 7c1f8d6e509..0708f9d2e7e 100755 --- a/library/jesd204/jesd204_tx/jesd204_tx.v +++ b/library/jesd204/jesd204_tx/jesd204_tx.v @@ -16,6 +16,7 @@ module jesd204_tx #( parameter DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4, parameter TPL_DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4, parameter ENABLE_CHAR_REPLACE = 1'b0, + parameter ENABLE_FEC = 0, parameter ASYNC_CLK = 1 ) ( input clk, @@ -51,6 +52,7 @@ module jesd204_tx #( input cfg_skip_ilas, input [7:0] cfg_mframes_per_ilas, input cfg_disable_char_replacement, + input [1:0] cfg_header_mode, input cfg_disable_scrambler, input [9:0] device_cfg_octets_per_multiframe, @@ -417,8 +419,9 @@ module jesd204_tx #( localparam D_STOP = D_START + DATA_PATH_WIDTH*8-1; localparam H_START = i * 2; localparam H_STOP = H_START + 2 -1; - - jesd204_tx_lane_64b i_lane ( + jesd204_tx_lane_64b #( + .ENABLE_FEC(ENABLE_FEC) + ) i_lane( .clk(clk), .reset(reset), @@ -433,7 +436,7 @@ module jesd204_tx #( .eoemb(eoemb), .cfg_disable_scrambler(cfg_disable_scrambler), - .cfg_header_mode(2'b0), + .cfg_header_mode(cfg_header_mode), .cfg_lane_disable(cfg_lanes_disable[i])); end diff --git a/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v b/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v index eb2e293f197..9ce93783dc3 100644 --- a/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v +++ b/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v @@ -1,13 +1,15 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2017, 2018, 2020-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2017, 2018, 2020-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** `timescale 1ns/100ps -module jesd204_tx_lane_64b ( +module jesd204_tx_lane_64b #( + parameter ENABLE_FEC = 1'b0 +) ( input clk, input reset, @@ -28,15 +30,22 @@ module jesd204_tx_lane_64b ( ); reg [63:0] scrambled_data; + reg [63:0] scrambled_data_d1; reg lmc_edge_d1 = 'b0; reg lmc_edge_d2 = 'b0; + reg lmc_edge_d3 = 'b0; reg lmc_quarter_edge_d1 = 'b0; reg lmc_quarter_edge_d2 = 'b0; + reg lmc_quarter_edge_d3 = 'b0; reg tx_ready_d1 = 'b0; + reg tx_ready_d2 = 'b0; + reg eoemb_d1 = 'b0; + reg [11:0] crc12_d1 = 'b0; wire [63:0] tx_data_msb_s; wire [63:0] scrambled_data_r; wire [11:0] crc12; + wire [25:0] fec; /* Reorder octets MSB first */ genvar i; @@ -59,17 +68,23 @@ module jesd204_tx_lane_64b ( always @(posedge clk) begin lmc_edge_d1 <= lmc_edge; lmc_edge_d2 <= lmc_edge_d1; + lmc_edge_d3 <= lmc_edge_d2; lmc_quarter_edge_d1 <= lmc_quarter_edge; lmc_quarter_edge_d2 <= lmc_quarter_edge_d1; + lmc_quarter_edge_d3 <= lmc_quarter_edge_d2; end always @(posedge clk) begin scrambled_data <= scrambled_data_r; - phy_data <= scrambled_data; + scrambled_data_d1 <= scrambled_data; + phy_data <= scrambled_data_d1; end always @(posedge clk) begin tx_ready_d1 <= tx_ready; + tx_ready_d2 <= tx_ready_d1; + eoemb_d1 <= eoemb; + crc12_d1 <= crc12; end jesd204_crc12 i_crc12 ( @@ -79,20 +94,35 @@ module jesd204_tx_lane_64b ( .data_in(scrambled_data), .crc12(crc12)); + if(ENABLE_FEC) begin : gen_fec + jesd204_fec_encode #( + .DATA_WIDTH (64) + ) jesd204_fec_encode ( + .fec (fec), + .clk (clk), + .rst (~tx_ready), + .shift_en (tx_ready_d2), + .eomb (lmc_edge_d2), + .data_in (scrambled_data) + ); + end else begin : gen_no_fec + assign fec = 26'b0; + end + jesd204_tx_header i_header_gen ( .clk(clk), .reset(~tx_ready | cfg_lane_disable), .cfg_header_mode(cfg_header_mode), - .lmc_edge(lmc_edge_d2), - .lmc_quarter_edge(lmc_quarter_edge_d2), + .lmc_edge(lmc_edge_d3), + .lmc_quarter_edge(lmc_quarter_edge_d3), // Header content to be sent must be valid during lmc_edge - .eoemb(eoemb), + .eoemb(eoemb_d1), .crc3(3'b0), - .crc12(crc12), - .fec(26'b0), + .crc12(crc12_d1), + .fec(fec), .cmd(19'b0), .header(phy_header)); diff --git a/library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v b/library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v index fd7add3f096..f840eb324b8 100755 --- a/library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v +++ b/library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2017, 2018, 2020-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2017, 2018, 2020-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -18,6 +18,7 @@ module jesd204_tx_static_config #( parameter HIGH_DENSITY = 1, parameter SCR = 1, parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B + parameter HEADER_MODE = 0, // 0 - CRC12 ; 1 - CRC3; 2 - FEC; 3 - CMD parameter SYSREF_DISABLE = 0, parameter SYSREF_ONE_SHOT = 0, /* Only 4, 8 are supported at the moment for 8b/10b and 8 for 64b */ @@ -35,6 +36,7 @@ module jesd204_tx_static_config #( output cfg_skip_ilas, output [7:0] cfg_mframes_per_ilas, output cfg_disable_char_replacement, + output [1:0] cfg_header_mode, output cfg_disable_scrambler, output [9:0] device_cfg_octets_per_multiframe, @@ -58,6 +60,7 @@ module jesd204_tx_static_config #( assign cfg_skip_ilas = 1'b0; assign cfg_mframes_per_ilas = 3; assign cfg_disable_char_replacement = 1'b0; + assign cfg_header_mode = HEADER_MODE; assign cfg_disable_scrambler = SCR ? 1'b0 : 1'b1; assign device_cfg_octets_per_multiframe = (FRAMES_PER_MULTIFRAME * OCTETS_PER_FRAME) - 1; diff --git a/library/jesd204/tb/sim_jesd204_fec.sh b/library/jesd204/tb/sim_jesd204_fec.sh new file mode 100755 index 00000000000..ccbf8dc3f65 --- /dev/null +++ b/library/jesd204/tb/sim_jesd204_fec.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# module load xlm + +xmvlog -sv ../jesd204_common/lfsr_input.sv +xmvlog ../../../ad_common/fpga_src/ad_mem_dist.v +xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv +xmvlog -sv ../jesd204_rx/jesd204_rx_fec_lfsr.sv +xmvlog -sv ../jesd204_rx/jesd204_fec_decode.sv +xmvlog -sv tb_link_layer_fec.v +xmelab -LICQUEUE -access +rwc -timescale 1ns/1ns tb_link_layer_fec + +if [ "$#" -ne 1 ]; then + xmsim -gui tb_link_layer_fec & +fi + diff --git a/library/jesd204/tb/sim_jesd204_fec_encode.sh b/library/jesd204/tb/sim_jesd204_fec_encode.sh new file mode 100755 index 00000000000..baa36224f42 --- /dev/null +++ b/library/jesd204/tb/sim_jesd204_fec_encode.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# module load xlm + +xmvlog -sv ../jesd204_common/lfsr_input.sv +xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv +xmvlog -sv tb_jesd204_fec_encode.sv +xmelab -access +rwc -timescale 1ns/1ns tb_jesd204_fec_encode + +if [ "$#" -ne 1 ]; then + xmsim -gui tb_jesd204_fec_encode & +fi diff --git a/library/jesd204/tb/sim_lfsr_input.sh b/library/jesd204/tb/sim_lfsr_input.sh new file mode 100755 index 00000000000..0227481e77e --- /dev/null +++ b/library/jesd204/tb/sim_lfsr_input.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# module load xlm + +xmvlog -sv ../jesd204_common/lfsr_input.sv +xmvlog -sv tb_lfsr_input.sv +xmelab -access +rwc -timescale 1ns/1ns tb_lfsr_input + +if [ "$#" -ne 1 ]; then + xmsim -gui tb_lfsr_input & +fi diff --git a/library/jesd204/tb/sim_link_layer_fec.sh b/library/jesd204/tb/sim_link_layer_fec.sh new file mode 100755 index 00000000000..85d12646bb3 --- /dev/null +++ b/library/jesd204/tb/sim_link_layer_fec.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# module load xlm + +xmvlog ../../../util_cdc/fpga_src/sync_bits.v +xmvlog ../../../util_cdc/fpga_src/sync_event.v + +xmvlog ../jesd204_common/jesd204_lmfc.v +xmvlog ../jesd204_common/jesd204_scrambler.v +xmvlog ../jesd204_common/jesd204_scrambler_64b.v +xmvlog ../jesd204_common/jesd204_crc12.v +xmvlog ../jesd204_common/jesd204_frame_mark.v +xmvlog ../jesd204_common/jesd204_frame_align_replace.v +xmvlog ../jesd204_common/pipeline_stage.v + +xmvlog -sv ../jesd204_common/lfsr_input.sv +xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv +xmvlog ../jesd204_tx/jesd204_tx_lane.v +xmvlog ../jesd204_tx/jesd204_tx_lane_64b.v +xmvlog ../jesd204_tx/jesd204_tx_gearbox.v +xmvlog ../jesd204_tx/jesd204_tx_header.v +xmvlog ../jesd204_tx/jesd204_tx_ctrl.v +xmvlog ../jesd204_tx/jesd204_tx.v + +xmvlog ../../../ad_common/fpga_src/ad_mem_dist.v +xmvlog -sv ../jesd204_rx/jesd204_rx_fec_lfsr.sv +xmvlog -sv ../jesd204_rx/jesd204_fec_decode.sv +xmvlog ../jesd204_rx/jesd204_rx_lane.v +xmvlog ../jesd204_rx/jesd204_rx_lane_64b.v +xmvlog ../jesd204_rx/jesd204_rx_header.v +xmvlog ../jesd204_rx/jesd204_rx_cgs.v +xmvlog ../jesd204_rx/jesd204_rx_ctrl.v +xmvlog ../jesd204_rx/jesd204_rx_ctrl_64b.v +xmvlog ../jesd204_rx/elastic_buffer.v +xmvlog ../jesd204_rx/error_monitor.v +xmvlog ../jesd204_rx/jesd204_ilas_monitor.v +xmvlog ../jesd204_rx/align_mux.v +xmvlog ../jesd204_rx/jesd204_lane_latency_monitor.v +xmvlog ../jesd204_rx/jesd204_rx_frame_align.v +xmvlog ../jesd204_rx/jesd204_rx.v + +xmvlog ../jesd204_rx_static_config/jesd204_rx_static_config.v +xmvlog ../jesd204_tx_static_config/jesd204_tx_static_config.v +xmvlog ../jesd204_tx_static_config/jesd204_ilas_cfg_static.v + +xmvlog -sv tb_link_layer_fec.sv +xmelab -LICQUEUE -access +rwc -timescale 1ns/1ns tb_link_layer_fec + +if [ "$#" -ne 1 ]; then + xmsim -LICQUEUE -gui tb_link_layer_fec & +fi diff --git a/library/jesd204/tb/tb_jesd204_fec.sv b/library/jesd204/tb/tb_jesd204_fec.sv new file mode 100755 index 00000000000..1e8aa6b322c --- /dev/null +++ b/library/jesd204/tb/tb_jesd204_fec.sv @@ -0,0 +1,151 @@ +`timescale 1ns / 100ps +`default_nettype none + +module tb_jesd204_fec; + + localparam FEC_WIDTH = 26; + localparam DATA_WIDTH = 64; + + // localparam INPUT_DATA_WIDTH = 64; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = 64'h8001020305050423; + localparam INPUT_DATA_WIDTH = 2048*4; + localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {{2048{1'b1}}, 1'b1, 2047'b0, {2048{1'b1}}, 2047'b0, 1'b1}; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {2047'b0, 1'b1}; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {1'b1, 63'b0, 1'b1, 1983'b0}; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {INPUT_DATA_WIDTH{1'b1}}; + localparam ERROR_CYCLE = 33; // Cycle of decoder data input to corrupt + localparam ERROR_BITS = 64'h1FF000; // Bits of decoder input data to corrupt + localparam FEC_ERROR_BITS = '0; // {1'b1, 25'b0}; + + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; + logic [INPUT_DATA_WIDTH-1:0] data; + + logic [FEC_WIDTH-1:0] fec; + logic [FEC_WIDTH-1:0] fec_saved; + logic [FEC_WIDTH-1:0] decode_fec_in; + reg clk = 1'b0; + logic rst; + logic fec_in_valid; + logic shift_en; + logic data_in_valid; + logic [DATA_WIDTH-1:0] data_in; + logic [DATA_WIDTH-1:0] decode_data_in; + logic [DATA_WIDTH-1:0] data_out; + logic data_out_valid; + logic trapped_error_flag; + logic untrapped_error_flag; + logic eomb; + logic [27:1] eomb_d; + + int data_in_cnt; + int decode_cnt; + int cycle_cnt; + int ii; + + always #5 clk = ~clk; + + initial begin + // Shift data in MSb-first by reversing the data + for(ii = 0; ii < INPUT_DATA_WIDTH; ii = ii + 1) begin + DATA_VALUE_REVERSED[ii] = DATA_VALUE[INPUT_DATA_WIDTH-1-ii]; + end + rst = 1'b1; + #100ns; + rst = 1'b0; + end + + always_ff @(posedge clk) begin + if(rst) begin + shift_en <= 1'b0; + data <= DATA_VALUE_REVERSED; + data_in_cnt <= '0; + data_in_valid <= 1'b0; + end else begin + data_in_valid <= 1'b1; + if(data_in_cnt < INPUT_DATA_WIDTH) begin + data_in <= data[0+:DATA_WIDTH]; + data <= data >> DATA_WIDTH; + shift_en <= 1'b1; + data_in_cnt <= data_in_cnt + DATA_WIDTH; + end else begin + shift_en <= 1'b0; + end + end + end + + always_ff @(posedge clk) begin + if(rst) begin + cycle_cnt <= '0; + end else begin + if(data_in_valid) begin + if(cycle_cnt == 31) begin + cycle_cnt <= '0; + end else begin + cycle_cnt <= cycle_cnt + 1'b1; + end + end + end + end + + assign eomb = cycle_cnt == 31; + // assign eomb = (data_in_cnt == INPUT_DATA_WIDTH) && shift_en; + + always_ff @(posedge clk) begin + if(rst) begin + decode_cnt <= '0; + end else begin + if(shift_en) begin + decode_cnt <= decode_cnt + 1; + end + end + end + + assign decode_data_in = (decode_cnt == ERROR_CYCLE) ? (data_in ^ ERROR_BITS) : data_in; + assign decode_fec_in = fec_saved ^ FEC_ERROR_BITS; + + jesd204_fec_encode #( + .DATA_WIDTH (DATA_WIDTH) + ) jesd204_fec_encode ( + .fec (fec), + .clk (clk), + .rst (rst), + .shift_en (data_in_valid), + .eomb (eomb), + .data_in (data_in) + ); + + always_ff @(posedge clk) begin + if(rst) begin + eomb_d <= '0; + end else begin + eomb_d <= {eomb_d[26:1], eomb}; + end + end + + always_ff @(posedge clk) begin + if(eomb_d[1]) begin + fec_saved <= fec; + end + end + + assign fec_in_valid = eomb_d[27]; + + jesd204_fec_decode #( + .DATA_WIDTH (DATA_WIDTH) + ) jesd204_fec_decode ( + .data_out (data_out), + .data_out_valid (data_out_valid), + .trapped_error_flag (trapped_error_flag), + .untrapped_error_flag (untrapped_error_flag), + .clk (clk), + .rst (rst), + .eomb (eomb), + .fec_in_valid (fec_in_valid), + .fec_in (decode_fec_in), + .data_in (decode_data_in) + ); + + +endmodule + +`default_nettype wire diff --git a/library/jesd204/tb/tb_jesd204_fec_encode.v b/library/jesd204/tb/tb_jesd204_fec_encode.v new file mode 100755 index 00000000000..bf4352e121b --- /dev/null +++ b/library/jesd204/tb/tb_jesd204_fec_encode.v @@ -0,0 +1,67 @@ +`timescale 1ns / 100ps +`default_nettype none + +module tb_jesd204_fec_encode; + + localparam FEC_WIDTH = 26; + localparam DATA_WIDTH = 64; + + // localparam INPUT_DATA_WIDTH = 64; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = 64'h8001020305050423; + localparam INPUT_DATA_WIDTH = 2048; + localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {1'b1, 2047'b0}; + + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; + logic [DATA_WIDTH-1:0] data; + + logic [FEC_WIDTH-1:0] fec; + reg clk = 1'b0; + logic rst; + logic shift_en; + logic [DATA_WIDTH-1:0] data_in; + + int data_in_cnt; + int ii; + + always #5 clk = ~clk; + + initial begin + // Shift data in MSb-first by reversing the data + for(ii = 0; ii < INPUT_DATA_WIDTH; ii = ii + 1) begin + DATA_VALUE_REVERSED[ii] = DATA_VALUE[INPUT_DATA_WIDTH-1-ii]; + end + rst = 1'b1; + #100ns; + rst = 1'b0; + end + + always_ff @(posedge clk) begin + if(rst) begin + shift_en <= 1'b0; + data <= DATA_VALUE_REVERSED; + data_in_cnt <= '0; + end else begin + if(data_in_cnt < INPUT_DATA_WIDTH) begin + data_in <= data[0+:DATA_WIDTH]; + data <= data >> DATA_WIDTH; + shift_en <= 1'b1; + data_in_cnt <= data_in_cnt + DATA_WIDTH; + end else begin + shift_en <= 1'b0; + end + end + end + + jesd204_fec_encode #( + .DATA_WIDTH (DATA_WIDTH) + ) jesd204_fec_encode ( + .fec (fec), + .clk (clk), + .rst (rst), + .shift_en (shift_en), + .data_in (data_in) + ); + +endmodule + +`default_nettype wire diff --git a/library/jesd204/tb/tb_lfsr_input.sv b/library/jesd204/tb/tb_lfsr_input.sv new file mode 100755 index 00000000000..f7390c3e7e8 --- /dev/null +++ b/library/jesd204/tb/tb_lfsr_input.sv @@ -0,0 +1,95 @@ +`timescale 1ns / 100ps +`default_nettype none + + +module tb_lfsr_input; + + localparam LFSR_WIDTH = 26; + localparam [LFSR_WIDTH:1] RESET_VAL = {LFSR_WIDTH{1'b0}}; + localparam [LFSR_WIDTH:1] LFSR_POLYNOMIAL = 26'h2210110; + localparam MAX_SHIFT_CNT = 64; + + // localparam INPUT_DATA_WIDTH = 64; + // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = 64'h8001020305050423; + localparam INPUT_DATA_WIDTH = 2048; + localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {1'b1, 2047'b0}; + + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; + logic [MAX_SHIFT_CNT-1:0] data; + + logic [MAX_SHIFT_CNT-1:0] data_out; + logic [LFSR_WIDTH:1] shift_reg; + reg clk = 1'b0; + logic rst; + logic shift_en; + logic [$clog2(MAX_SHIFT_CNT)-1:0] shift_cnt; + logic [MAX_SHIFT_CNT-1:0] data_in; + + int data_in_cnt; + int ii; + + always #5 clk = ~clk; + + // 𝑥^26 + 𝑥^21 + 𝑥^17 + 𝑥^9 + 𝑥^4 + 1 + // 100001000100000001000010001 + // Remove the MSb (x^26) term because it represents the loopback from LSb of the LFSR to the MSb + // 0000 1000 1000 0000 1000 0100 01 + // Reverse the order of the taps because the LSb of the LFSR contains the MSb of the FEC data + // 10 0010 0001 0000 0001 0001 0000 + + // S0 S25 FEC register index + // 26 1 LFSR_POLYNOMIAL index + // X0001000010000000100010000 + // X0 0010 0001 0000 0001 0001 0000 + + + + + + initial begin + for(ii = 0; ii < INPUT_DATA_WIDTH; ii = ii + 1) begin + DATA_VALUE_REVERSED[ii] = DATA_VALUE[INPUT_DATA_WIDTH-1-ii]; + end + rst = 1'b1; + #100ns; + rst = 1'b0; + end + + always_ff @(posedge clk) begin + if(rst) begin + shift_en <= 1'b0; + data <= DATA_VALUE_REVERSED; + data_in_cnt <= '0; + end else begin + if(data_in_cnt < INPUT_DATA_WIDTH) begin + // Shift data in MSb-first by reversing the data + data_in <= data[0+:MAX_SHIFT_CNT]; + data <= data >> (shift_cnt+1); + shift_en <= 1'b1; + data_in_cnt <= data_in_cnt + (shift_cnt + 1); + end else begin + shift_en <= 1'b0; + end + end + end + + assign shift_cnt = 63; + + lfsr_input #( + .LFSR_WIDTH (LFSR_WIDTH), + .RESET_VAL (RESET_VAL), + .LFSR_POLYNOMIAL (LFSR_POLYNOMIAL), + .MAX_SHIFT_CNT (MAX_SHIFT_CNT) + ) lfsr_input ( + .data_out (data_out), + .shift_reg (shift_reg), + .clk (clk), + .rst (rst), + .shift_en (shift_en), + .shift_cnt (shift_cnt), + .data_in (data_in) + ); + +endmodule + +`default_nettype wire diff --git a/library/jesd204/tb/tb_link_layer_fec.sv b/library/jesd204/tb/tb_link_layer_fec.sv new file mode 100755 index 00000000000..a0adcb775e8 --- /dev/null +++ b/library/jesd204/tb/tb_link_layer_fec.sv @@ -0,0 +1,420 @@ +`timescale 1ns / 100ps +`default_nettype none + +module tb_link_layer_fec; + + localparam NUM_LANES=2; + localparam NUM_LINKS=1; + localparam SCR = 0; + localparam DATA_PATH_WIDTH = 8; + localparam DATA_WIDTH = DATA_PATH_WIDTH*8; + + localparam INPUT_DATA_WIDTH = 2048*9*2; + localparam INPUT_DATA_CYCLES = INPUT_DATA_WIDTH/DATA_WIDTH; + localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {2{{2048{1'b1}}, 1'b1, 2047'b0, {64{32'h12345678}}, {2048{1'b1}}, 2047'b0, 1'b1, {64{32'hABCDEF01}}, {64{32'h23456789}}, {2048{1'b1}}, 1'b1, 2047'b0}}; + localparam ERROR_CYCLE = (32*8)+4; // Cycle of decoder data input to corrupt + // localparam RECOVERABLE_ERROR_BITS = 64'h1FF000; + localparam RECOVERABLE_ERROR_BITS = 64'h8000000000000000; + localparam UNRECOVERABLE_ERROR_BITS = 64'h1FFFFF; + localparam ERROR_BITS = RECOVERABLE_ERROR_BITS; // Bits of decoder input data to corrupt + localparam NEXT_ERROR_BITS = 64'h1; + // localparam NEXT_ERROR_BITS = 64'h0000000000000000; + localparam REPORT_GOOD_DATA = 1'b1; + + reg clk = 1'b0; + reg sysref = 1'b0; + logic rst; + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; + logic [INPUT_DATA_WIDTH-1:0] data; + logic [DATA_WIDTH-1:0] data_in; + logic [DATA_WIDTH-1:0] data_in_swap; + int data_in_cnt; + int ii; + int tx_cycle_cnt; + int rx_cycle_cnt; + genvar jj; + + logic [NUM_LANES-1:0] tx_cfg_lanes_disable; + logic [NUM_LINKS-1:0] tx_cfg_links_disable; + logic [9:0] tx_cfg_octets_per_multiframe; + logic [7:0] tx_cfg_octets_per_frame; + logic [9:0] tx_device_cfg_octets_per_multiframe; + logic [7:0] tx_device_cfg_octets_per_frame; + logic [7:0] tx_device_cfg_beats_per_multiframe; + logic [7:0] tx_device_cfg_lmfc_offset; + logic tx_device_cfg_sysref_oneshot; + logic tx_device_cfg_sysref_disable; + logic tx_cfg_continuous_cgs; + logic tx_cfg_continuous_ilas; + logic tx_cfg_skip_ilas; + logic [7:0] tx_cfg_mframes_per_ilas; + logic tx_cfg_disable_char_replacement; + logic [1:0] tx_cfg_header_mode; + logic tx_cfg_disable_scrambler; + logic tx_lmfc_edge; + logic tx_lmfc_clk; + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data; + logic tx_ready; + logic [DATA_PATH_WIDTH-1:0] tx_eof; + logic [DATA_PATH_WIDTH-1:0] tx_sof; + logic [DATA_PATH_WIDTH-1:0] tx_somf; + logic [DATA_PATH_WIDTH-1:0] tx_eomf; + logic tx_valid; + + logic [NUM_LANES-1:0] rx_cfg_lanes_disable; + logic [NUM_LINKS-1:0] rx_cfg_links_disable; + logic [9:0] rx_cfg_octets_per_multiframe; + logic [7:0] rx_cfg_octets_per_frame; + logic [9:0] rx_device_cfg_octets_per_multiframe; + logic [7:0] rx_device_cfg_octets_per_frame; + logic [7:0] rx_device_cfg_beats_per_multiframe; + logic [7:0] rx_device_cfg_lmfc_offset; + logic rx_device_cfg_sysref_oneshot; + logic rx_device_cfg_sysref_disable; + logic [7:0] rx_device_cfg_buffer_delay; + logic rx_device_cfg_buffer_early_release; + logic rx_cfg_disable_scrambler; + logic rx_cfg_disable_char_replacement; + logic [1:0] rx_cfg_header_mode; + logic [7:0] rx_cfg_frame_align_err_threshold; + + + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_phy_data; + logic [2*NUM_LANES-1:0] tx_phy_header; + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] rx_phy_data; + logic [2*NUM_LANES-1:0] rx_phy_header; + logic [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_charisk; + logic [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_notintable; + logic [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_disperr; + logic [NUM_LANES-1:0] phy_block_sync; + logic rx_lmfc_edge; + logic rx_lmfc_clk; + logic phy_en_char_align; + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] rx_data; + logic rx_valid; + logic [DATA_PATH_WIDTH-1:0] rx_eof; + logic [DATA_PATH_WIDTH-1:0] rx_sof; + logic [DATA_PATH_WIDTH-1:0] rx_eomf; + logic [DATA_PATH_WIDTH-1:0] rx_somf; + logic rx_ctrl_err_statistics_reset; + logic [8:0] rx_ctrl_err_statistics_mask; + logic [32*NUM_LANES-1:0] rx_status_err_statistics_cnt; + + logic tx_data_dropped; + logic cur_error_cycle; + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data_q[$]; + logic [DATA_PATH_WIDTH*8*NUM_LANES-1:0] cur_tx_data; + + always #5ns clk = ~clk; + + always #(5ns*32*8) sysref = ~sysref; + + initial begin + rst = 1'b1; + #100ns; + rst = 1'b0; + end + + assign tx_valid = 1'b1; + // assign tx_data = {DATA_PATH_WIDTH*8*NUM_LANES{1'b1}}; + + initial begin + // Shift data in MSb-first by reversing the data + for(ii = 0; ii < INPUT_DATA_WIDTH; ii = ii + 1) begin + DATA_VALUE_REVERSED[ii] = DATA_VALUE[INPUT_DATA_WIDTH-1-ii]; + end + rst = 1'b1; + #100ns; + rst = 1'b0; + end + + initial begin + data = DATA_VALUE_REVERSED; + data_in_cnt = '0; + data_in = '0; + forever begin + data_in = data[0+:DATA_WIDTH]; + @(posedge clk); + #0; + if(tx_ready && (data_in_cnt < INPUT_DATA_CYCLES)) begin + data = data >> DATA_WIDTH; + data_in_cnt = data_in_cnt + 1; + end + end + end + + // // TX data is dropped until the first EoMB is seen + // initial begin + // tx_data_dropped = 1'b1; + // forever begin + // @(negedge clk); + // if(tx_ready & tx_eomf[DATA_PATH_WIDTH-1]) begin + // tx_data_dropped = 1'b0; + // end + // end + // end + + // The first 7 multiblocks of data are dropped, one by TX, 6 by RX + // TODO: is this dependent on TX data pattern when scrambling is disabled? + initial begin + tx_data_dropped = 1'b1; + forever begin + @(negedge clk); + if(tx_ready && (data_in_cnt >= (32 * 7))) begin + tx_data_dropped = 1'b0; + end + end + end + + // always_ff @(posedge clk) begin + // if(rst) begin + // data <= DATA_VALUE_REVERSED; + // data_in_cnt <= '0; + // data_in <= '0; + // end else begin + // if(tx_ready) begin + // if(data_in_cnt < INPUT_DATA_WIDTH) begin + // data_in <= data[0+:DATA_WIDTH]; + // data <= data >> DATA_WIDTH; + // data_in_cnt <= data_in_cnt + DATA_WIDTH; + // end + // end + // end + // end + + always_ff @(posedge clk) begin + if(rst) begin + tx_cycle_cnt <= '0; + end else begin + if(tx_ready) begin + tx_cycle_cnt <= tx_cycle_cnt + 1; + end + end + end + + // Swap order of octets + for(jj = 0; jj < DATA_PATH_WIDTH; jj=jj+1) begin : tx_data_gen + assign data_in_swap[jj*8+:8] = data_in[(DATA_PATH_WIDTH-jj-1)*8+:8]; + end + + assign tx_data = {NUM_LANES{data_in_swap}}; + + assign rx_phy_data = (tx_cycle_cnt == ERROR_CYCLE) ? (tx_phy_data ^ ERROR_BITS) : (tx_cycle_cnt == ERROR_CYCLE+1) ? (tx_phy_data ^ NEXT_ERROR_BITS) : tx_phy_data; + // assign rx_phy_data = tx_phy_data; + assign rx_phy_header = tx_phy_header; + + assign rx_ctrl_err_statistics_mask = 8'h3F; // FEC trapped and non-trapped error + assign rx_ctrl_err_statistics_reset = 1'b0; + + assign cur_error_cycle = tx_cycle_cnt == ERROR_CYCLE; + + initial begin + tx_data_q = {}; + forever begin + @(negedge clk); + if(tx_ready && !tx_data_dropped && (data_in_cnt < INPUT_DATA_CYCLES)) begin + tx_data_q.push_back(tx_data); + // $display("%t TX Cycle %d: %X", $time, tx_cycle_cnt, tx_data); + end + end + end + + initial begin + rx_cycle_cnt = 0; + forever begin + @(negedge clk); + if(rx_valid) begin + if(tx_data_q.size() == 0) begin + $finish; + end + cur_tx_data = tx_data_q.pop_front(); + if(cur_tx_data !== rx_data) begin + $error("RX Cycle: %d Data mismatch. Expected: %X Observed: %X", rx_cycle_cnt, cur_tx_data, rx_data); + end else if(REPORT_GOOD_DATA) begin + $display("RX Cycle: %d Good data:%X", rx_cycle_cnt, cur_tx_data); + end + rx_cycle_cnt = rx_cycle_cnt + 1; + end + end + end + + jesd204_tx_static_config #( + .NUM_LANES (NUM_LANES), + .OCTETS_PER_FRAME(8), + .FRAMES_PER_MULTIFRAME(32), + .SCR (SCR), + .LINK_MODE (2), + .HEADER_MODE (2) + ) jesd204_tx_static_config ( + .clk (clk), + .cfg_lanes_disable (tx_cfg_lanes_disable), + .cfg_links_disable (tx_cfg_links_disable), + .cfg_octets_per_multiframe (tx_cfg_octets_per_multiframe), + .cfg_octets_per_frame (tx_cfg_octets_per_frame), + .device_cfg_octets_per_multiframe (tx_device_cfg_octets_per_multiframe), + .device_cfg_octets_per_frame (tx_device_cfg_octets_per_frame), + .device_cfg_beats_per_multiframe (tx_device_cfg_beats_per_multiframe), + .device_cfg_lmfc_offset (tx_device_cfg_lmfc_offset), + .device_cfg_sysref_oneshot (tx_device_cfg_sysref_oneshot), + .device_cfg_sysref_disable (tx_device_cfg_sysref_disable), + .cfg_continuous_cgs (tx_cfg_continuous_cgs), + .cfg_continuous_ilas (tx_cfg_continuous_ilas), + .cfg_skip_ilas (tx_cfg_skip_ilas), + .cfg_mframes_per_ilas (tx_cfg_mframes_per_ilas), + .cfg_disable_char_replacement (tx_cfg_disable_char_replacement), + .cfg_header_mode (tx_cfg_header_mode), + .cfg_disable_scrambler (tx_cfg_disable_scrambler), + .ilas_config_rd(), + .ilas_config_addr(), + .ilas_config_data() + ); + + jesd204_tx #( + .NUM_LANES (NUM_LANES), + .NUM_LINKS (NUM_LINKS), + .NUM_INPUT_PIPELINE (1), + .NUM_OUTPUT_PIPELINE (0), + .LINK_MODE (2), + .ENABLE_FEC (1), + .DATA_PATH_WIDTH (DATA_PATH_WIDTH) + ) jesd204_tx ( + .clk (clk), + .reset (rst), + .device_clk (clk), + .device_reset (rst), + .phy_data (tx_phy_data), + .phy_charisk (phy_charisk), + .phy_header (tx_phy_header), + .sysref (sysref), + .lmfc_edge (tx_lmfc_edge), + .lmfc_clk (tx_lmfc_clk), + .sync ('0), + .tx_data (tx_data), + .tx_ready (tx_ready), + .tx_eof (tx_eof), + .tx_sof (tx_sof), + .tx_eomf (tx_eomf), + .tx_somf (tx_somf), + .tx_valid (tx_valid), + .cfg_lanes_disable (tx_cfg_lanes_disable), + .cfg_links_disable (tx_cfg_links_disable), + .cfg_octets_per_multiframe (tx_cfg_octets_per_multiframe), + .cfg_octets_per_frame (tx_cfg_octets_per_frame), + .device_cfg_octets_per_multiframe (tx_device_cfg_octets_per_multiframe), + .device_cfg_octets_per_frame (tx_device_cfg_octets_per_frame), + .device_cfg_beats_per_multiframe (tx_device_cfg_beats_per_multiframe), + .device_cfg_lmfc_offset (tx_device_cfg_lmfc_offset), + .device_cfg_sysref_oneshot (tx_device_cfg_sysref_oneshot), + .device_cfg_sysref_disable (tx_device_cfg_sysref_disable), + .cfg_continuous_cgs (tx_cfg_continuous_cgs), + .cfg_continuous_ilas (tx_cfg_continuous_ilas), + .cfg_skip_ilas (tx_cfg_skip_ilas), + .cfg_mframes_per_ilas (tx_cfg_mframes_per_ilas), + .cfg_disable_char_replacement (tx_cfg_disable_char_replacement), + .cfg_header_mode (tx_cfg_header_mode), + .cfg_disable_scrambler (tx_cfg_disable_scrambler), + .ilas_config_rd (), + .ilas_config_addr (), + .ilas_config_data ('0), + .ctrl_manual_sync_request (), + .device_event_sysref_edge (), + .device_event_sysref_alignment_error (), + .status_sync (), + .status_state () + ); + + + + jesd204_rx_static_config #( + .NUM_LANES (NUM_LANES), + .OCTETS_PER_FRAME (8), + .FRAMES_PER_MULTIFRAME (32), + .SCR (SCR), + .LINK_MODE (2), + .HEADER_MODE (2), + .SYSREF_DISABLE (0) + ) jesd204_rx_static_config( + .clk (clk), + .cfg_lanes_disable (rx_cfg_lanes_disable), + .cfg_links_disable (rx_cfg_links_disable), + .cfg_disable_scrambler (rx_cfg_disable_scrambler), + .cfg_disable_char_replacement (rx_cfg_disable_char_replacement), + .cfg_header_mode (rx_cfg_header_mode), + .cfg_frame_align_err_threshold (rx_cfg_frame_align_err_threshold), + .cfg_octets_per_multiframe (rx_cfg_octets_per_multiframe), + .cfg_octets_per_frame (rx_cfg_octets_per_frame), + .device_cfg_octets_per_multiframe (rx_device_cfg_octets_per_multiframe), + .device_cfg_octets_per_frame (rx_device_cfg_octets_per_frame), + .device_cfg_beats_per_multiframe (rx_device_cfg_beats_per_multiframe), + .device_cfg_lmfc_offset (rx_device_cfg_lmfc_offset), + .device_cfg_sysref_oneshot (rx_device_cfg_sysref_oneshot), + .device_cfg_sysref_disable (rx_device_cfg_sysref_disable), + .device_cfg_buffer_delay (rx_device_cfg_buffer_delay), + .device_cfg_buffer_early_release (rx_device_cfg_buffer_early_release) + ); + + + jesd204_rx #( + .NUM_LANES (NUM_LANES), + .LINK_MODE (2), + .ENABLE_FEC (1) + ) jesd204_rx ( + .clk (clk), + .reset (rst), + .device_clk (clk), + .device_reset (rst), + .phy_data (rx_phy_data), + .phy_header (rx_phy_header), + .phy_charisk ('0), + .phy_notintable ('0), + .phy_disperr ('0), + .phy_block_sync ('1), + .sysref (sysref), + .lmfc_edge (rx_lmfc_edge), + .lmfc_clk (rx_lmfc_clk), + .device_event_sysref_alignment_error (), + .device_event_sysref_edge (), + .event_frame_alignment_error (), + .event_unexpected_lane_state_error (), + .sync (), + .phy_en_char_align (), + .rx_data (rx_data), + .rx_valid (rx_valid), + .rx_eof (rx_eof), + .rx_sof (rx_sof), + .rx_eomf (rx_eomf), + .rx_somf (rx_somf), + .cfg_lanes_disable (rx_cfg_lanes_disable), + .cfg_links_disable (rx_cfg_links_disable), + .cfg_octets_per_multiframe (rx_cfg_octets_per_multiframe), + .cfg_octets_per_frame (rx_cfg_octets_per_frame), + .device_cfg_octets_per_multiframe (rx_device_cfg_octets_per_multiframe), + .device_cfg_octets_per_frame (rx_device_cfg_octets_per_frame), + .device_cfg_beats_per_multiframe (rx_device_cfg_beats_per_multiframe), + .cfg_disable_scrambler (rx_cfg_disable_scrambler), + .cfg_disable_char_replacement (rx_cfg_disable_char_replacement), + .cfg_header_mode (rx_cfg_header_mode), + .cfg_frame_align_err_threshold (rx_cfg_frame_align_err_threshold), + .device_cfg_lmfc_offset (rx_device_cfg_lmfc_offset), + .device_cfg_sysref_disable (rx_device_cfg_sysref_disable), + .device_cfg_sysref_oneshot (rx_device_cfg_sysref_oneshot), + .device_cfg_buffer_early_release (rx_device_cfg_buffer_early_release), + .device_cfg_buffer_delay (rx_device_cfg_buffer_delay), + .ctrl_err_statistics_reset (rx_ctrl_err_statistics_reset), + .ctrl_err_statistics_mask (rx_ctrl_err_statistics_mask), + .status_err_statistics_cnt (rx_status_err_statistics_cnt), + .ilas_config_valid (), + .ilas_config_addr (), + .ilas_config_data (), + .status_ctrl_state (), + .status_lane_cgs_state (), + .status_lane_ifs_ready (), + .status_lane_latency (), + .status_lane_emb_state (), + .status_lane_frame_align_err_cnt () + ); + + +endmodule + +`default_nettype wire From ac4a7fd299d97b6217640a28f0b6cfafdf1f508d Mon Sep 17 00:00:00 2001 From: "Matthew.Blanton" Date: Mon, 8 Jan 2024 10:22:21 -0500 Subject: [PATCH 02/11] Changes to help with timing --- library/common/ad_mem_dist.v | 33 ++++++++++ .../axi_jesd204_common/jesd204_up_sysref.v | 8 ++- .../jesd204/axi_jesd204_rx/axi_jesd204_rx.v | 15 +++-- .../axi_jesd204_rx/axi_jesd204_rx_constr.xdc | 57 +++++++++------- .../jesd204/axi_jesd204_rx/jesd204_up_rx.v | 7 +- .../jesd204/axi_jesd204_tx/axi_jesd204_tx.v | 6 +- .../axi_jesd204_tx/axi_jesd204_tx_constr.xdc | 65 ++++++++++++++----- library/jesd204/jesd204_rx/Makefile | 1 + .../jesd204_rx/jesd204_lane_latency_monitor.v | 4 +- library/jesd204/jesd204_rx/jesd204_rx.xdc | 2 + .../jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v | 36 +++++----- library/jesd204/jesd204_rx/jesd204_rx_ip.tcl | 2 + .../jesd204/jesd204_rx/jesd204_rx_lane_64b.v | 28 ++++++-- library/jesd204/jesd204_tx/Makefile | 1 + library/jesd204/jesd204_tx/jesd204_tx.v | 55 ++++++++++++---- library/jesd204/jesd204_tx/jesd204_tx.xdc | 2 + library/jesd204/jesd204_tx/jesd204_tx_ip.tcl | 2 + .../jesd204/jesd204_tx/jesd204_tx_lane_64b.v | 2 +- 18 files changed, 234 insertions(+), 92 deletions(-) create mode 100755 library/common/ad_mem_dist.v mode change 100644 => 100755 library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc create mode 100755 library/jesd204/jesd204_rx/jesd204_rx.xdc mode change 100644 => 100755 library/jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v mode change 100644 => 100755 library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v create mode 100755 library/jesd204/jesd204_tx/jesd204_tx.xdc mode change 100644 => 100755 library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v diff --git a/library/common/ad_mem_dist.v b/library/common/ad_mem_dist.v new file mode 100755 index 00000000000..29d8ee79555 --- /dev/null +++ b/library/common/ad_mem_dist.v @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////////////// +// Company: Analog Devices, Inc. +// Engineer: MBB +// Simple dual-port distributed RAM with non-registered output +////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ps / 1ps +`default_nettype none + +module dual_port_dist_ram #( + parameter RAM_WIDTH = 32, + parameter RAM_ADDR_BITS = 4 +)( + output wire [RAM_WIDTH-1:0] rd_data, + input wire clk, + input wire wr_en, + input wire [RAM_ADDR_BITS-1:0] wr_addr, + input wire [RAM_WIDTH-1:0] wr_data, + input wire [RAM_ADDR_BITS-1:0] rd_addr +); + + (* ram_style="distributed" *) + reg [RAM_WIDTH-1:0] ram [(2**RAM_ADDR_BITS)-1:0]; + + always @(posedge clk) + if (wr_en) + ram[wr_addr] <= wr_data; + + assign rd_data = ram[rd_addr]; + +endmodule + +`default_nettype wire diff --git a/library/jesd204/axi_jesd204_common/jesd204_up_sysref.v b/library/jesd204/axi_jesd204_common/jesd204_up_sysref.v index 9c624922df1..712f1e81a6e 100755 --- a/library/jesd204/axi_jesd204_common/jesd204_up_sysref.v +++ b/library/jesd204/axi_jesd204_common/jesd204_up_sysref.v @@ -1,13 +1,15 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2016-2018, 2020-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2016-2018, 2020-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** `timescale 1ns/100ps -module jesd204_up_sysref ( +module jesd204_up_sysref #( + parameter DATA_PATH_WIDTH_LOG2 = 0 +) ( input up_clk, input up_reset, @@ -90,7 +92,7 @@ module jesd204_up_sysref ( end 12'h041: begin /* Must be aligned to data path width */ - up_cfg_lmfc_offset <= up_wdata; + up_cfg_lmfc_offset <= up_wdata[9:DATA_PATH_WIDTH_LOG2]; end endcase end diff --git a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v index 07f404c09b1..e1dd545180a 100755 --- a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v +++ b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v @@ -93,7 +93,9 @@ module axi_jesd204_rx #( localparam PCORE_VERSION = 32'h00010761; // 1.07.a localparam PCORE_MAGIC = 32'h32303452; // 204R - + + localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2; + /* Register interface signals */ reg [31:0] up_rdata = 'h0; reg up_wack = 1'b0; @@ -242,9 +244,11 @@ module axi_jesd204_rx #( .status_synth_params1(status_synth_params1), .status_synth_params2(status_synth_params2)); - jesd204_up_sysref i_up_sysref ( - .up_clk(s_axi_aclk), - .up_reset(up_reset), + jesd204_up_sysref #( + .DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2) + ) i_up_sysref ( + .up_clk(s_axi_aclk), + .up_reset(up_reset), .core_clk(core_clk), .device_clk(device_clk), @@ -265,7 +269,8 @@ module axi_jesd204_rx #( jesd204_up_rx #( .NUM_LANES(NUM_LANES), - .DATA_PATH_WIDTH(DATA_PATH_WIDTH) + .DATA_PATH_WIDTH(DATA_PATH_WIDTH), + .DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2) ) i_up_rx ( .up_clk(s_axi_aclk), .up_reset(up_reset), diff --git a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc index aa6023365a9..488ee8423e5 100755 --- a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc +++ b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc @@ -1,5 +1,5 @@ ############################################################################### -## Copyright (C) 2016-2018, 2020-2021 Analog Devices, Inc. All rights reserved. +## Copyright (C) 2016-2018, 2020-2021, 2025 Analog Devices, Inc. All rights reserved. ### SPDX short identifier: ADIJESD204 ############################################################################### @@ -18,6 +18,11 @@ set_property ASYNC_REG TRUE \ [get_cells -hier {up_reset_synchronizer_vector_reg*}] \ [get_cells -hier {up_core_reset_ext_synchronizer_vector_reg*}] +set_false_path \ + -to [get_cells i_up_rx/gen_lane[*].i_up_rx_lane/up_status_latency_reg[*]] + # -to [get_cells -hierarchical * -filter {NAME=~datapath/datapath_rx/jesd204_rx_link_layer/link_gen[*].jesd204c_rx/axi_jesd204_rx/i_up_rx/gen_lane[*].i_up_rx_lane/up_status_latency_reg[*] && IS_SEQUENTIAL}] + + set_false_path \ -from [get_pins {i_up_rx/i_cdc_status/in_toggle_d1_reg/C}] \ -to [get_pins {i_up_rx/i_cdc_status/i_sync_out/cdc_sync_stage1_reg[0]/D}] @@ -59,19 +64,27 @@ set_false_path \ -to [get_pins {i_sync_frame_align_err/out_event_reg*/D}] # Don't place them too far appart -set_max_delay -datapath_only \ +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_rx/i_cdc_status/cdc_hold_reg[*]/C}] \ +# -to [get_pins {i_up_rx/i_cdc_status/out_data_reg[*]/D}] \ +# [get_property -min PERIOD $axi_clk] + +set_false_path \ -from [get_pins {i_up_rx/i_cdc_status/cdc_hold_reg[*]/C}] \ - -to [get_pins {i_up_rx/i_cdc_status/out_data_reg[*]/D}] \ - [get_property -min PERIOD $axi_clk] + -to [get_pins {i_up_rx/i_cdc_status/out_data_reg[*]/D}] set_false_path \ -from $core_clk \ -to [get_pins {i_up_rx/*i_up_rx_lane/i_cdc_status_ready/cdc_sync_stage1_reg*/D}] -set_max_delay -datapath_only \ +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_rx/i_cdc_cfg/cdc_hold_reg[*]/C}] \ +# -to [get_pins {i_up_rx/i_cdc_cfg/out_data_reg[*]/D}] \ +# [get_property -min PERIOD $core_clk] + +set_false_path \ -from [get_pins {i_up_rx/i_cdc_cfg/cdc_hold_reg[*]/C}] \ - -to [get_pins {i_up_rx/i_cdc_cfg/out_data_reg[*]/D}] \ - [get_property -min PERIOD $core_clk] + -to [get_pins {i_up_rx/i_cdc_cfg/out_data_reg[*]/D}] set_max_delay -datapath_only \ -from $core_clk \ @@ -103,27 +116,27 @@ set_false_path \ set_false_path \ -to [get_pins {i_up_common/up_core_reset_ext_synchronizer_vector_reg[*]/PRE}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_cfg_*_reg*/D}] \ - [get_property -min PERIOD $core_clk] + -to [get_pins {i_up_common/core_cfg_*_reg*/D}] + # [get_property -min PERIOD $core_clk] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_cfg_*_reg*/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_cfg_*_reg*/D}] + # [get_property -min PERIOD $device_clk] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $core_clk] + -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] + # [get_property -min PERIOD $core_clk] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] + # [get_property -min PERIOD $device_clk] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] + # [get_property -min PERIOD $device_clk] diff --git a/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v b/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v index 5457d662bbe..e998699f896 100755 --- a/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v +++ b/library/jesd204/axi_jesd204_rx/jesd204_up_rx.v @@ -9,7 +9,8 @@ module jesd204_up_rx #( parameter NUM_LANES = 1, - parameter DATA_PATH_WIDTH = 4 + parameter DATA_PATH_WIDTH = 4, + parameter DATA_PATH_WIDTH_LOG2 = 2 ) ( input up_clk, input up_reset, @@ -105,7 +106,7 @@ module jesd204_up_rx #( /* 17-31 */ 15'h00, /* Reserved for future additions */ /* 16 */ up_cfg_buffer_early_release, /* Release buffer as soon as all lanes are ready. */ /* 10-15 */ 6'b0000, /* Reserved for future extensions of buffer_delay */ - /* 02-09 */ up_cfg_buffer_delay, /* Buffer release delay */ + /* 02-09 */ up_cfg_buffer_delay << (DATA_PATH_WIDTH_LOG2-2), /* Buffer release delay */ /* 00-01 */ 2'b00 /* Data path width alignment */ }; 12'h91: up_rdata <= { @@ -150,7 +151,7 @@ module jesd204_up_rx #( /* JESD RX configuraton */ 12'h090: begin up_cfg_buffer_early_release <= up_wdata[16]; - up_cfg_buffer_delay <= up_wdata[9:2]; + up_cfg_buffer_delay <= up_wdata[9:DATA_PATH_WIDTH_LOG2]; end endcase end else if (up_wreq == 1'b1) begin diff --git a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v index c6e83f4ed3c..9f10941a504 100755 --- a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v +++ b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v @@ -86,6 +86,8 @@ module axi_jesd204_tx #( localparam PCORE_VERSION = 32'h00010661; // 1.06.a localparam PCORE_MAGIC = 32'h32303454; // 204T + localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2; + wire up_reset; /* Register interface signals */ @@ -222,7 +224,9 @@ module axi_jesd204_tx #( .status_synth_params1(status_synth_params1), .status_synth_params2(status_synth_params2)); - jesd204_up_sysref i_up_sysref ( + jesd204_up_sysref #( + .DATA_PATH_WIDTH_LOG2 (DATA_PATH_WIDTH_LOG2) + ) i_up_sysref ( .up_clk(s_axi_aclk), .up_reset(up_reset), diff --git a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc old mode 100644 new mode 100755 index 9d51f20c131..a2d1b82e619 --- a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc +++ b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc @@ -63,35 +63,64 @@ set_false_path \ set_false_path \ -to [get_pins {i_up_common/up_core_reset_ext_synchronizer_vector_reg[*]/PRE}] -set_max_delay -datapath_only \ +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ +# -to [get_pins {i_up_common/core_cfg_*_reg*/D}] \ +# [get_property -min PERIOD $core_clk] + +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ +# -to [get_pins {i_up_common/device_cfg_*_reg*/D}] \ +# [get_property -min PERIOD $device_clk] + +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_tx/up_cfg_ilas_data_*_reg*/C}] \ +# -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] \ +# [get_property -min PERIOD $core_clk] + +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ +# -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \ +# [get_property -min PERIOD $core_clk] + +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ +# -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ +# [get_property -min PERIOD $device_clk] + +# set_max_delay -datapath_only \ +# -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ +# -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ +# [get_property -min PERIOD $device_clk] + + + + +set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_cfg_*_reg*/D}] \ - [get_property -min PERIOD $core_clk] + -to [get_pins {i_up_common/core_cfg_*_reg*/D}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_cfg_*_reg*/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_cfg_*_reg*/D}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_tx/up_cfg_ilas_data_*_reg*/C}] \ - -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] \ - [get_property -min PERIOD $core_clk] + -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $core_clk] + -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] -set_max_delay -datapath_only \ +set_false_path \ -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ - [get_property -min PERIOD $device_clk] + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] + + set_false_path \ -from [get_pins {i_up_tx/i_cdc_manual_sync_request/out_toggle_d1_reg/C}] \ diff --git a/library/jesd204/jesd204_rx/Makefile b/library/jesd204/jesd204_rx/Makefile index 8242d3af260..da539caaa91 100644 --- a/library/jesd204/jesd204_rx/Makefile +++ b/library/jesd204/jesd204_rx/Makefile @@ -28,6 +28,7 @@ XILINX_DEPS += jesd204_rx_header.v XILINX_DEPS += jesd204_rx_ip.tcl XILINX_DEPS += jesd204_rx_lane_64b.v XILINX_DEPS += jesd204_rx_ooc.ttcl +XILINX_DEPS += jesd204_rx.xdc XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_cfg.xml XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_cfg_rtl.xml diff --git a/library/jesd204/jesd204_rx/jesd204_lane_latency_monitor.v b/library/jesd204/jesd204_rx/jesd204_lane_latency_monitor.v index b7284074307..32d33ddb78f 100755 --- a/library/jesd204/jesd204_rx/jesd204_lane_latency_monitor.v +++ b/library/jesd204/jesd204_rx/jesd204_lane_latency_monitor.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2017, 2018, 2021, 2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2017, 2018, 2021, 2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -51,7 +51,7 @@ module jesd204_lane_latency_monitor #( end end - assign lane_latency[i*14+13:i*14] = {lane_latency_mem[i],lane_frame_align[(i*3)+DPW_LOG2-1:i*3]}; + assign lane_latency[i*14+13:i*14] = {lane_latency_mem[i],lane_frame_align[(i*DPW_LOG2)+DPW_LOG2-1:i*DPW_LOG2]}; assign lane_latency_ready[i] = lane_captured[i]; end endgenerate diff --git a/library/jesd204/jesd204_rx/jesd204_rx.xdc b/library/jesd204/jesd204_rx/jesd204_rx.xdc new file mode 100755 index 00000000000..eacdf94b8bc --- /dev/null +++ b/library/jesd204/jesd204_rx/jesd204_rx.xdc @@ -0,0 +1,2 @@ +set_false_path -through [get_ports {cfg_*}] +set_false_path -through [get_ports {core_cfg_*}] \ No newline at end of file diff --git a/library/jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v b/library/jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v old mode 100644 new mode 100755 index 9fa08355b25..351f330dc4b --- a/library/jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v +++ b/library/jesd204/jesd204_rx/jesd204_rx_ctrl_64b.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2017, 2018, 2020-2022 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2017, 2018, 2020-2022, 2025 Analog Devices, Inc. All rights reserved. // SPDX short identifier: ADIJESD204 // *************************************************************************** // *************************************************************************** @@ -19,7 +19,7 @@ module jesd204_rx_ctrl_64b #( input [NUM_LANES-1:0] emb_lock, - output all_emb_lock, + output reg all_emb_lock, input buffer_release_n, output [1:0] status_state, @@ -37,24 +37,24 @@ module jesd204_rx_ctrl_64b #( reg rst_good_cnt; reg event_unexpected_lane_state_error_nx; - wire [NUM_LANES-1:0] phy_block_sync_masked; - wire [NUM_LANES-1:0] emb_lock_masked; - wire all_block_sync; - - reg [NUM_LANES-1:0] emb_lock_d = {NUM_LANES{1'b0}}; - reg buffer_release_d_n = 1'b1; + reg [NUM_LANES-1:0] phy_block_sync_masked; + reg [NUM_LANES-1:0] emb_lock_masked; + reg all_block_sync; always @(posedge clk) begin - emb_lock_d <= emb_lock; - buffer_release_d_n <= buffer_release_n; + if (reset == 1'b1) begin + phy_block_sync_masked <= {NUM_LANES{1'b0}}; + emb_lock_masked <= {NUM_LANES{1'b0}}; + all_block_sync <= 1'b0; + all_emb_lock <= 1'b0; + end else begin + phy_block_sync_masked <= phy_block_sync | cfg_lanes_disable; + emb_lock_masked <= emb_lock | cfg_lanes_disable; + all_block_sync <= &phy_block_sync_masked; + all_emb_lock <= &emb_lock_masked; + end end - assign phy_block_sync_masked = phy_block_sync | cfg_lanes_disable; - assign emb_lock_masked = emb_lock_d | cfg_lanes_disable; - - assign all_block_sync = &phy_block_sync_masked; - assign all_emb_lock = &emb_lock_masked; - always @(*) begin next_state = state; rst_good_cnt = 1'b1; @@ -72,7 +72,7 @@ module jesd204_rx_ctrl_64b #( STATE_BLOCK_SYNC: if (~all_block_sync) begin next_state = STATE_WAIT_BS; - end else if (all_emb_lock & ~buffer_release_d_n) begin + end else if (all_emb_lock & ~buffer_release_n) begin rst_good_cnt = 1'b0; if (&good_cnt) begin next_state = STATE_DATA; @@ -82,7 +82,7 @@ module jesd204_rx_ctrl_64b #( if (~all_block_sync) begin next_state = STATE_WAIT_BS; event_unexpected_lane_state_error_nx = 1'b1; - end else if (~all_emb_lock | buffer_release_d_n) begin + end else if (~all_emb_lock | buffer_release_n) begin next_state = STATE_BLOCK_SYNC; event_unexpected_lane_state_error_nx = 1'b1; end diff --git a/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl b/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl index 18c2d995b6f..26147f6e16c 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl +++ b/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl @@ -25,8 +25,10 @@ adi_ip_files jesd204_rx [list \ "jesd204_rx_constr.ttcl" \ "jesd204_rx_ooc.ttcl" \ "jesd204_rx.v" \ + "jesd204_rx.xdc" \ "../../common/ad_pack.v" \ "../../common/ad_upack.v" \ + "../../common/util_pipeline_stage.v" \ "bd/bd.tcl" ] diff --git a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v old mode 100644 new mode 100755 index cbb248d72ae..969cf5d463c --- a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v +++ b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v @@ -45,7 +45,7 @@ module jesd204_rx_lane_64b #( output reg [7:0] status_lane_skew ); - reg [11:0] crc12_calculated_prev; + reg [11:0] crc12_calculated_prev; wire [63:0] phy_data_r; wire [63:0] data_descrambled_s; @@ -109,11 +109,25 @@ module jesd204_rx_lane_64b #( .event_unexpected_eomb(event_unexpected_eomb), .event_unexpected_eoemb(event_unexpected_eoemb)); + util_pipeline_stage #( + .WIDTH(65), + .REGISTERED(1) + ) i_pipeline_crc12 ( + .clk(clk), + .in({ + eomb, + phy_data + }), + .out({ + eomb_r, + phy_data_r + })); + jesd204_crc12 i_crc12 ( .clk(clk), - .reset(1'b0), - .init(eomb), - .data_in(phy_data), + .reset(reset), + .init(eomb_r), + .data_in(phy_data_r), .crc12(crc12_calculated)); reg crc12_on = 'b0; @@ -129,18 +143,18 @@ module jesd204_rx_lane_64b #( always @(posedge clk) begin if (reset == 1'b1) begin crc12_rdy <= 1'b0; - end else if (crc12_on && eomb) begin + end else if (crc12_on && eomb_r) begin crc12_rdy <= 1'b1; end end always @(posedge clk) begin - if (eomb) begin + if (eomb_r) begin crc12_calculated_prev <= crc12_calculated; end end - assign event_crc12_mismatch = crc12_rdy && eomb && (crc12_calculated_prev != crc12_received); + assign event_crc12_mismatch = crc12_rdy && eomb_r && (crc12_calculated_prev != crc12_received); assign err_cnt_rst = reset || ctrl_err_statistics_reset; diff --git a/library/jesd204/jesd204_tx/Makefile b/library/jesd204/jesd204_tx/Makefile index 7c33b7de0ca..6497197ebe0 100644 --- a/library/jesd204/jesd204_tx/Makefile +++ b/library/jesd204/jesd204_tx/Makefile @@ -19,6 +19,7 @@ XILINX_DEPS += jesd204_tx_header.v XILINX_DEPS += jesd204_tx_ip.tcl XILINX_DEPS += jesd204_tx_lane_64b.v XILINX_DEPS += jesd204_tx_ooc.ttcl +XILINX_DEPS += jesd204_tx.xdc XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_cfg.xml XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_cfg_rtl.xml diff --git a/library/jesd204/jesd204_tx/jesd204_tx.v b/library/jesd204/jesd204_tx/jesd204_tx.v index 0708f9d2e7e..a429ee9a109 100755 --- a/library/jesd204/jesd204_tx/jesd204_tx.v +++ b/library/jesd204/jesd204_tx/jesd204_tx.v @@ -10,6 +10,7 @@ module jesd204_tx #( parameter NUM_LANES = 1, parameter NUM_LINKS = 1, + parameter NUM_INPUT_PIPELINE = 0, parameter NUM_OUTPUT_PIPELINE = 0, parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B /* Only 4 is supported at the moment for 8b/10b and 8 for 64b */ @@ -98,11 +99,17 @@ module jesd204_tx #( localparam DW = DATA_PATH_WIDTH * 8 * NUM_LANES; localparam CW = DATA_PATH_WIDTH * NUM_LANES; localparam HW = 2 * NUM_LANES; + localparam INPUT_PIPELINE_WIDTH = (LINK_MODE[0] == 1) ? (1+(NUM_LANES*(1+(DATA_PATH_WIDTH*19)))) : (4+(64*NUM_LANES)); + +wire [DW-1:0] tx_data_r; +wire tx_ready_r; wire [DW-1:0] phy_data_r; wire [CW-1:0] phy_charisk_r; wire [HW-1:0] phy_header_r; + wire [INPUT_PIPELINE_WIDTH-1:0] input_pipeline_in; + wire [INPUT_PIPELINE_WIDTH-1:0] input_pipeline_out; wire eof_gen_reset; wire tx_ready_64b_next; reg tx_ready_64b = 1'b0; @@ -318,6 +325,14 @@ module jesd204_tx #( tx_eomf_fm_d2 <= tx_eomf_fm_d1; end + util_pipeline_stage #( + .WIDTH(INPUT_PIPELINE_WIDTH), + .REGISTERED(NUM_INPUT_PIPELINE) + ) i_input_pipeline_stage ( + .clk(clk), + .in(input_pipeline_in), + .out(input_pipeline_out)); + generate genvar i; @@ -329,8 +344,17 @@ module jesd204_tx #( wire [DW-1:0] ilas_data; wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk; + wire [DATA_PATH_WIDTH-1:0] tx_eof_fm_d3_r; + wire [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d3_r; + wire [NUM_LANES-1:0] lane_cgs_enable_r; + wire [DW-1:0] ilas_data_r; + wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk_r; + wire cfg_generate_eomf = 1'b1; + assign input_pipeline_in = {tx_ready, gearbox_data, ilas_charisk, ilas_data, lane_cgs_enable, tx_eomf_fm_d3, tx_eof_fm_d3}; + assign {tx_ready_r, tx_data_r, ilas_charisk_r, ilas_data_r, lane_cgs_enable_r, tx_eomf_fm_d3_r, tx_eof_fm_d3_r} = input_pipeline_out; + always @(posedge clk) begin tx_eof_fm_d3 <= tx_eof_fm_d2; tx_eomf_fm_d3 <= tx_eomf_fm_d2; @@ -389,16 +413,16 @@ module jesd204_tx #( ) i_lane ( .clk(clk), - .eof(tx_eof_fm_d3), - .eomf(tx_eomf_fm_d3), + .eof(tx_eof_fm_d3_r), + .eomf(tx_eomf_fm_d3_r), - .cgs_enable(lane_cgs_enable[i]), + .cgs_enable(lane_cgs_enable_r[i]), - .ilas_data(ilas_data[D_STOP:D_START]), - .ilas_charisk(ilas_charisk[C_STOP:C_START]), + .ilas_data(ilas_data_r[D_STOP:D_START]), + .ilas_charisk(ilas_charisk_r[C_STOP:C_START]), - .tx_data(gearbox_data[D_STOP:D_START]), - .tx_ready(link_tx_ready), + .tx_data(tx_data_r[D_STOP:D_START]), + .tx_ready(tx_ready_r), .phy_data(phy_data_r[D_STOP:D_START]), .phy_charisk(phy_charisk_r[C_STOP:C_START]), @@ -413,6 +437,13 @@ module jesd204_tx #( end if (LINK_MODE[1] == 1) begin : mode_64b66b + wire lmc_edge_r; + wire lmc_quarter_edge_r; + wire eoemb_r; + wire tx_ready_64b_r; + + assign input_pipeline_in = {eoemb, lmc_quarter_edge, lmc_edge, tx_ready_64b, gearbox_data}; + assign {eoemb_r, lmc_quarter_edge_r, lmc_edge_r, tx_ready_64b_r, tx_data_r} = input_pipeline_out; for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane localparam D_START = i * DATA_PATH_WIDTH*8; @@ -425,15 +456,15 @@ module jesd204_tx #( .clk(clk), .reset(reset), - .tx_data(gearbox_data[D_STOP:D_START]), - .tx_ready(tx_ready_64b), + .tx_data(tx_data_r[D_STOP:D_START]), + .tx_ready(tx_ready_64b_r), .phy_data(phy_data_r[D_STOP:D_START]), .phy_header(phy_header_r[H_STOP:H_START]), - .lmc_edge(lmc_edge), - .lmc_quarter_edge(lmc_quarter_edge), - .eoemb(eoemb), + .lmc_edge(lmc_edge_r), + .lmc_quarter_edge(lmc_quarter_edge_r), + .eoemb(eoemb_r), .cfg_disable_scrambler(cfg_disable_scrambler), .cfg_header_mode(cfg_header_mode), diff --git a/library/jesd204/jesd204_tx/jesd204_tx.xdc b/library/jesd204/jesd204_tx/jesd204_tx.xdc new file mode 100755 index 00000000000..eacdf94b8bc --- /dev/null +++ b/library/jesd204/jesd204_tx/jesd204_tx.xdc @@ -0,0 +1,2 @@ +set_false_path -through [get_ports {cfg_*}] +set_false_path -through [get_ports {core_cfg_*}] \ No newline at end of file diff --git a/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl b/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl index 9fd5bf9ca92..59c3c83d52b 100644 --- a/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl +++ b/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl @@ -17,8 +17,10 @@ adi_ip_files jesd204_tx [list \ "jesd204_tx_ctrl.v" \ "jesd204_tx_constr.ttcl" \ "jesd204_tx_ooc.ttcl" \ + "jesd204_tx.xdc" \ "../../common/ad_pack.v" \ "../../common/ad_upack.v" \ + "../../common/util_pipeline_stage.v" \ "jesd204_tx.v" \ "bd/bd.tcl" ] diff --git a/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v b/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v old mode 100644 new mode 100755 index 9ce93783dc3..73da0fd4290 --- a/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v +++ b/library/jesd204/jesd204_tx/jesd204_tx_lane_64b.v @@ -60,7 +60,7 @@ module jesd204_tx_lane_64b #( .DESCRAMBLE(0) ) i_scrambler ( .clk(clk), - .reset(1'b0), + .reset(reset), .enable(~cfg_disable_scrambler), .data_in(tx_data_msb_s), .data_out(scrambled_data_r)); From d85cc208beef9dc5f7109025cebf8f0bd173e663 Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Tue, 5 Aug 2025 11:19:39 +0300 Subject: [PATCH 03/11] library: jesd204: jesd204_rx_lane_64b: Fixed crc mismatch Signed-off-by: Bogdan Luncan --- library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v index 969cf5d463c..3e4463dc998 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v +++ b/library/jesd204/jesd204_rx/jesd204_rx_lane_64b.v @@ -48,6 +48,7 @@ module jesd204_rx_lane_64b #( reg [11:0] crc12_calculated_prev; wire [63:0] phy_data_r; + wire [11:0] crc12_received_r; wire [63:0] data_descrambled_s; wire [63:0] data_descrambled; wire [63:0] data_descrambled_reordered; @@ -110,16 +111,18 @@ module jesd204_rx_lane_64b #( .event_unexpected_eoemb(event_unexpected_eoemb)); util_pipeline_stage #( - .WIDTH(65), + .WIDTH(1+12+64), .REGISTERED(1) ) i_pipeline_crc12 ( .clk(clk), .in({ eomb, + crc12_received, phy_data }), .out({ eomb_r, + crc12_received_r, phy_data_r })); @@ -154,7 +157,7 @@ module jesd204_rx_lane_64b #( end end - assign event_crc12_mismatch = crc12_rdy && eomb_r && (crc12_calculated_prev != crc12_received); + assign event_crc12_mismatch = crc12_rdy && eomb_r && (crc12_calculated_prev != crc12_received_r); assign err_cnt_rst = reset || ctrl_err_statistics_reset; From 79de919b3328d14fb57dd09bdcd70f24734de947 Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Tue, 5 Aug 2025 17:34:15 +0300 Subject: [PATCH 04/11] library: jesd204: jesd204_tx: Fixed pipeline for 8b10b Signed-off-by: Bogdan Luncan --- library/jesd204/jesd204_tx/jesd204_tx.v | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/library/jesd204/jesd204_tx/jesd204_tx.v b/library/jesd204/jesd204_tx/jesd204_tx.v index a429ee9a109..2881c80c68c 100755 --- a/library/jesd204/jesd204_tx/jesd204_tx.v +++ b/library/jesd204/jesd204_tx/jesd204_tx.v @@ -99,7 +99,7 @@ module jesd204_tx #( localparam DW = DATA_PATH_WIDTH * 8 * NUM_LANES; localparam CW = DATA_PATH_WIDTH * NUM_LANES; localparam HW = 2 * NUM_LANES; - localparam INPUT_PIPELINE_WIDTH = (LINK_MODE[0] == 1) ? (1+(NUM_LANES*(1+(DATA_PATH_WIDTH*19)))) : (4+(64*NUM_LANES)); + localparam INPUT_PIPELINE_WIDTH = (LINK_MODE[0] == 1) ? (1+(NUM_LANES*(1+(DATA_PATH_WIDTH*21)))) : (4+(64*NUM_LANES)); wire [DW-1:0] tx_data_r; wire tx_ready_r; @@ -338,27 +338,20 @@ wire tx_ready_r; if (LINK_MODE[0] == 1) begin : mode_8b10b - reg [DATA_PATH_WIDTH-1:0] tx_eof_fm_d3; - reg [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d3; wire [NUM_LANES-1:0] lane_cgs_enable; wire [DW-1:0] ilas_data; wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk; - wire [DATA_PATH_WIDTH-1:0] tx_eof_fm_d3_r; - wire [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d3_r; + wire [DATA_PATH_WIDTH-1:0] tx_eof_fm_d2_r; + wire [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d2_r; wire [NUM_LANES-1:0] lane_cgs_enable_r; wire [DW-1:0] ilas_data_r; wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk_r; wire cfg_generate_eomf = 1'b1; - assign input_pipeline_in = {tx_ready, gearbox_data, ilas_charisk, ilas_data, lane_cgs_enable, tx_eomf_fm_d3, tx_eof_fm_d3}; - assign {tx_ready_r, tx_data_r, ilas_charisk_r, ilas_data_r, lane_cgs_enable_r, tx_eomf_fm_d3_r, tx_eof_fm_d3_r} = input_pipeline_out; - - always @(posedge clk) begin - tx_eof_fm_d3 <= tx_eof_fm_d2; - tx_eomf_fm_d3 <= tx_eomf_fm_d2; - end + assign input_pipeline_in = {link_tx_ready, gearbox_data, ilas_charisk, ilas_data, lane_cgs_enable, tx_eomf_fm_d2, tx_eof_fm_d2}; + assign {tx_ready_r, tx_data_r, ilas_charisk_r, ilas_data_r, lane_cgs_enable_r, tx_eomf_fm_d2_r, tx_eof_fm_d2_r} = input_pipeline_out; jesd204_tx_ctrl #( .NUM_LANES(NUM_LANES), @@ -413,8 +406,8 @@ wire tx_ready_r; ) i_lane ( .clk(clk), - .eof(tx_eof_fm_d3_r), - .eomf(tx_eomf_fm_d3_r), + .eof(tx_eof_fm_d2_r), + .eomf(tx_eomf_fm_d2_r), .cgs_enable(lane_cgs_enable_r[i]), From 316c9c33fc2ac9f1d6ae974e90e2f1774835d061 Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Tue, 5 Aug 2025 17:34:42 +0300 Subject: [PATCH 05/11] library: common: ad_mem_dist: Rename and add registered output Signed-off-by: Bogdan Luncan --- library/common/ad_mem_dist.v | 64 +++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/library/common/ad_mem_dist.v b/library/common/ad_mem_dist.v index 29d8ee79555..6e612b5a38d 100755 --- a/library/common/ad_mem_dist.v +++ b/library/common/ad_mem_dist.v @@ -1,15 +1,44 @@ -////////////////////////////////////////////////////////////////////////////////// -// Company: Analog Devices, Inc. -// Engineer: MBB -// Simple dual-port distributed RAM with non-registered output -////////////////////////////////////////////////////////////////////////////////// +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** -`timescale 1ps / 1ps -`default_nettype none +`timescale 1ns/100ps -module dual_port_dist_ram #( +module ad_mem_dist #( parameter RAM_WIDTH = 32, - parameter RAM_ADDR_BITS = 4 + parameter RAM_ADDR_BITS = 4, + parameter REGISTERED_OUTPUT = 1 )( output wire [RAM_WIDTH-1:0] rd_data, input wire clk, @@ -22,12 +51,23 @@ module dual_port_dist_ram #( (* ram_style="distributed" *) reg [RAM_WIDTH-1:0] ram [(2**RAM_ADDR_BITS)-1:0]; + reg [RAM_WIDTH-1:0] rd_data_s; + always @(posedge clk) if (wr_en) ram[wr_addr] <= wr_data; - assign rd_data = ram[rd_addr]; + generate if (REGISTERED_OUTPUT) begin + always @(posedge clk) begin + rd_data_s <= ram[rd_addr]; + end + end else begin + always @(*) begin + rd_data_s = ram[rd_addr]; + end + end + endgenerate -endmodule + assign rd_data = rd_data_s; -`default_nettype wire +endmodule From c7c55d62932899ea9bfdd3a3754d8f0e58e1880e Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Tue, 5 Aug 2025 17:35:54 +0300 Subject: [PATCH 06/11] library: jesd204: fec: Update licenses and cleanup Signed-off-by: Bogdan Luncan --- .../axi_jesd204_rx/axi_jesd204_rx_constr.xdc | 18 ------ .../axi_jesd204_tx/axi_jesd204_tx_constr.xdc | 49 +++------------ library/jesd204/jesd204_common/lfsr_input.sv | 49 ++------------- .../jesd204/jesd204_rx/jesd204_fec_decode.sv | 59 ++++--------------- library/jesd204/jesd204_rx/jesd204_rx.xdc | 7 ++- .../jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv | 53 +++-------------- .../jesd204/jesd204_tx/jesd204_fec_encode.sv | 50 ++-------------- library/jesd204/jesd204_tx/jesd204_tx.xdc | 7 ++- library/jesd204/jesd204_tx/jesd204_tx_hw.tcl | 5 ++ library/jesd204/tb/sim_jesd204_fec | 13 ++++ library/jesd204/tb/sim_jesd204_fec.sh | 16 ----- library/jesd204/tb/sim_jesd204_fec_encode | 10 ++++ library/jesd204/tb/sim_jesd204_fec_encode.sh | 12 ---- library/jesd204/tb/sim_lfsr_input | 9 +++ library/jesd204/tb/sim_lfsr_input.sh | 11 ---- library/jesd204/tb/sim_link_layer_fec | 48 +++++++++++++++ library/jesd204/tb/sim_link_layer_fec.sh | 51 ---------------- library/jesd204/tb/tb_jesd204_fec.sv | 8 ++- ..._fec_encode.v => tb_jesd204_fec_encode.sv} | 7 +++ library/jesd204/tb/tb_lfsr_input.sv | 10 +++- library/jesd204/tb/tb_link_layer_fec.sv | 8 +++ 21 files changed, 165 insertions(+), 335 deletions(-) create mode 100755 library/jesd204/tb/sim_jesd204_fec delete mode 100755 library/jesd204/tb/sim_jesd204_fec.sh create mode 100755 library/jesd204/tb/sim_jesd204_fec_encode delete mode 100755 library/jesd204/tb/sim_jesd204_fec_encode.sh create mode 100755 library/jesd204/tb/sim_lfsr_input delete mode 100755 library/jesd204/tb/sim_lfsr_input.sh create mode 100755 library/jesd204/tb/sim_link_layer_fec delete mode 100755 library/jesd204/tb/sim_link_layer_fec.sh rename library/jesd204/tb/{tb_jesd204_fec_encode.v => tb_jesd204_fec_encode.sv} (80%) diff --git a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc index 488ee8423e5..7843dc54692 100755 --- a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc +++ b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx_constr.xdc @@ -20,8 +20,6 @@ set_property ASYNC_REG TRUE \ set_false_path \ -to [get_cells i_up_rx/gen_lane[*].i_up_rx_lane/up_status_latency_reg[*]] - # -to [get_cells -hierarchical * -filter {NAME=~datapath/datapath_rx/jesd204_rx_link_layer/link_gen[*].jesd204c_rx/axi_jesd204_rx/i_up_rx/gen_lane[*].i_up_rx_lane/up_status_latency_reg[*] && IS_SEQUENTIAL}] - set_false_path \ -from [get_pins {i_up_rx/i_cdc_status/in_toggle_d1_reg/C}] \ @@ -63,12 +61,6 @@ set_false_path \ -from [get_pins {i_sync_frame_align_err/cdc_hold_reg*/C}] \ -to [get_pins {i_sync_frame_align_err/out_event_reg*/D}] -# Don't place them too far appart -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_rx/i_cdc_status/cdc_hold_reg[*]/C}] \ -# -to [get_pins {i_up_rx/i_cdc_status/out_data_reg[*]/D}] \ -# [get_property -min PERIOD $axi_clk] - set_false_path \ -from [get_pins {i_up_rx/i_cdc_status/cdc_hold_reg[*]/C}] \ -to [get_pins {i_up_rx/i_cdc_status/out_data_reg[*]/D}] @@ -77,11 +69,6 @@ set_false_path \ -from $core_clk \ -to [get_pins {i_up_rx/*i_up_rx_lane/i_cdc_status_ready/cdc_sync_stage1_reg*/D}] -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_rx/i_cdc_cfg/cdc_hold_reg[*]/C}] \ -# -to [get_pins {i_up_rx/i_cdc_cfg/out_data_reg[*]/D}] \ -# [get_property -min PERIOD $core_clk] - set_false_path \ -from [get_pins {i_up_rx/i_cdc_cfg/cdc_hold_reg[*]/C}] \ -to [get_pins {i_up_rx/i_cdc_cfg/out_data_reg[*]/D}] @@ -119,24 +106,19 @@ set_false_path \ set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ -to [get_pins {i_up_common/core_cfg_*_reg*/D}] - # [get_property -min PERIOD $core_clk] set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ -to [get_pins {i_up_common/device_cfg_*_reg*/D}] - # [get_property -min PERIOD $device_clk] set_false_path \ -from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \ -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] - # [get_property -min PERIOD $core_clk] set_false_path \ -from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \ -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] - # [get_property -min PERIOD $device_clk] set_false_path \ -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] - # [get_property -min PERIOD $device_clk] diff --git a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc index a2d1b82e619..28998394b56 100755 --- a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc +++ b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx_constr.xdc @@ -1,5 +1,5 @@ ############################################################################### -## Copyright (C) 2017, 2018, 2021 Analog Devices, Inc. All rights reserved. +## Copyright (C) 2017, 2018, 2021, 2025 Analog Devices, Inc. All rights reserved. ### SPDX short identifier: ADIJESD204 ############################################################################### @@ -63,64 +63,29 @@ set_false_path \ set_false_path \ -to [get_pins {i_up_common/up_core_reset_ext_synchronizer_vector_reg[*]/PRE}] -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ -# -to [get_pins {i_up_common/core_cfg_*_reg*/D}] \ -# [get_property -min PERIOD $core_clk] - -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ -# -to [get_pins {i_up_common/device_cfg_*_reg*/D}] \ -# [get_property -min PERIOD $device_clk] - -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_tx/up_cfg_ilas_data_*_reg*/C}] \ -# -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] \ -# [get_property -min PERIOD $core_clk] - -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ -# -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \ -# [get_property -min PERIOD $core_clk] - -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ -# -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ -# [get_property -min PERIOD $device_clk] - -# set_max_delay -datapath_only \ -# -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ -# -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \ -# [get_property -min PERIOD $device_clk] - - - - set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_cfg_*_reg*/D}] + -to [get_pins {i_up_common/core_cfg_*_reg*/D}] set_false_path \ -from [get_pins {i_up_common/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_cfg_*_reg*/D}] + -to [get_pins {i_up_common/device_cfg_*_reg*/D}] set_false_path \ -from [get_pins {i_up_tx/up_cfg_ilas_data_*_reg*/C}] \ - -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] + -to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] set_false_path \ -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] + -to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] set_false_path \ -from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] set_false_path \ -from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \ - -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] - - + -to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] set_false_path \ -from [get_pins {i_up_tx/i_cdc_manual_sync_request/out_toggle_d1_reg/C}] \ diff --git a/library/jesd204/jesd204_common/lfsr_input.sv b/library/jesd204/jesd204_common/lfsr_input.sv index da13af0e2a7..b515b089cb4 100755 --- a/library/jesd204/jesd204_common/lfsr_input.sv +++ b/library/jesd204/jesd204_common/lfsr_input.sv @@ -1,46 +1,9 @@ -// -// The ADI JESD204 Core is released under the following license, which is -// different than all other HDL cores in this repository. -// -// Please read this, and understand the freedoms and responsibilities you have -// by using this source code/core. -// -// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. -// -// This core is free software, you can use run, copy, study, change, ask -// questions about and improve this core. Distribution of source, or resulting -// binaries (including those inside an FPGA or ASIC) require you to release the -// source of the entire project (excluding the system libraries provide by the -// tools/compiler/FPGA vendor). These are the terms of the GNU General Public -// License version 2 as published by the Free Software Foundation. -// -// This core is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -// A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License version 2 -// along with this source code, and binary. If not, see -// . -// -// Commercial licenses (with commercial support) of this JESD204 core are also -// available under terms different than the General Public License. (e.g. they -// do not require you to accompany any image (FPGA or ASIC) using the JESD204 -// core with any corresponding source code.) For these alternate terms you must -// purchase a license from Analog Devices Technology Licensing Office. Users -// interested in such a license should contact jesd204-licensing@analog.com for -// more information. This commercial license is sub-licensable (if you purchase -// chips from Analog Devices, incorporate them into your PCB level product, and -// purchase a JESD204 license, end users of your product will also have a -// license to use this core in a commercial setting without releasing their -// source code). -// -// In addition, we kindly ask you to acknowledge ADI in any program, application -// or publication in which you use this JESD204 HDL core. (You are not required -// to do so; it is up to your common sense to decide whether you want to comply -// with this request or not.) For general publications, we suggest referencing : -// “The design and implementation of the JESD204 HDL Core used in this project -// is copyright © 2016-2017, Analog Devices, Inc.” -// +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** `timescale 1ns / 100ps diff --git a/library/jesd204/jesd204_rx/jesd204_fec_decode.sv b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv index 9e1c5841849..59b9c4f7200 100755 --- a/library/jesd204/jesd204_rx/jesd204_fec_decode.sv +++ b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv @@ -1,47 +1,9 @@ -// -// The ADI JESD204 Core is released under the following license, which is -// different than all other HDL cores in this repository. -// -// Please read this, and understand the freedoms and responsibilities you have -// by using this source code/core. -// -// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. -// -// This core is free software, you can use run, copy, study, change, ask -// questions about and improve this core. Distribution of source, or resulting -// binaries (including those inside an FPGA or ASIC) require you to release the -// source of the entire project (excluding the system libraries provide by the -// tools/compiler/FPGA vendor). These are the terms of the GNU General Public -// License version 2 as published by the Free Software Foundation. -// -// This core is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -// A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License version 2 -// along with this source code, and binary. If not, see -// . -// -// Commercial licenses (with commercial support) of this JESD204 core are also -// available under terms different than the General Public License. (e.g. they -// do not require you to accompany any image (FPGA or ASIC) using the JESD204 -// core with any corresponding source code.) For these alternate terms you must -// purchase a license from Analog Devices Technology Licensing Office. Users -// interested in such a license should contact jesd204-licensing@analog.com for -// more information. This commercial license is sub-licensable (if you purchase -// chips from Analog Devices, incorporate them into your PCB level product, and -// purchase a JESD204 license, end users of your product will also have a -// license to use this core in a commercial setting without releasing their -// source code). -// -// In addition, we kindly ask you to acknowledge ADI in any program, application -// or publication in which you use this JESD204 HDL core. (You are not required -// to do so; it is up to your common sense to decide whether you want to comply -// with this request or not.) For general publications, we suggest referencing : -// “The design and implementation of the JESD204 HDL Core used in this project -// is copyright © 2016-2017, Analog Devices, Inc.” -// - +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** `timescale 1ns / 100ps @@ -92,7 +54,7 @@ module jesd204_fec_decode #( logic [BUFFER_ADDR_WIDTH-1:0] buf_rd_addr; logic [DATA_WIDTH-1:0] buf_wr_data; logic [DATA_WIDTH-1:0] buf_rd_data; - logic [DATA_WIDTH-1:0] buf_rd_data_d; + // logic [DATA_WIDTH-1:0] buf_rd_data_d; logic [3:1] eomb_d; logic data_in_en; logic fec_in_en; @@ -135,7 +97,8 @@ module jesd204_fec_decode #( // Data buffer ad_mem_dist #( .RAM_WIDTH (DATA_WIDTH), - .RAM_ADDR_BITS (BUFFER_ADDR_WIDTH) + .RAM_ADDR_BITS (BUFFER_ADDR_WIDTH), + .REGISTERED_OUTPUT (1) ) data_buffer ( .rd_data (buf_rd_data), .clk (clk), @@ -259,7 +222,7 @@ module jesd204_fec_decode #( always_ff @(posedge clk) begin error_syndrome_next_d <= error_syndrome_next; - buf_rd_data_d <= buf_rd_data; + // buf_rd_data_d <= buf_rd_data; end // Error is trapped if the MSb of the syndrome is 1 and bits 16:0 of the syndrome are 0 @@ -301,7 +264,7 @@ module jesd204_fec_decode #( // Correct data by XORing with FEC syndrome // Output corrected data always_ff @(posedge clk) begin - data_out <= buf_rd_data_d ^ error_bits[DATA_WIDTH-1:0] ^ error_bits_prev; + data_out <= buf_rd_data ^ error_bits[DATA_WIDTH-1:0] ^ error_bits_prev; data_out_valid <= data_out_en_d[1]; end diff --git a/library/jesd204/jesd204_rx/jesd204_rx.xdc b/library/jesd204/jesd204_rx/jesd204_rx.xdc index eacdf94b8bc..fa0f47ceb09 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx.xdc +++ b/library/jesd204/jesd204_rx/jesd204_rx.xdc @@ -1,2 +1,7 @@ +############################################################################### +## Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +# SPDX short identifier: ADIBSD +############################################################################### + set_false_path -through [get_ports {cfg_*}] -set_false_path -through [get_ports {core_cfg_*}] \ No newline at end of file +set_false_path -through [get_ports {core_cfg_*}] diff --git a/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv b/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv index 8dead64bfef..b7fbe06ce7f 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv +++ b/library/jesd204/jesd204_rx/jesd204_rx_fec_lfsr.sv @@ -1,46 +1,9 @@ -// -// The ADI JESD204 Core is released under the following license, which is -// different than all other HDL cores in this repository. -// -// Please read this, and understand the freedoms and responsibilities you have -// by using this source code/core. -// -// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. -// -// This core is free software, you can use run, copy, study, change, ask -// questions about and improve this core. Distribution of source, or resulting -// binaries (including those inside an FPGA or ASIC) require you to release the -// source of the entire project (excluding the system libraries provide by the -// tools/compiler/FPGA vendor). These are the terms of the GNU General Public -// License version 2 as published by the Free Software Foundation. -// -// This core is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -// A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License version 2 -// along with this source code, and binary. If not, see -// . -// -// Commercial licenses (with commercial support) of this JESD204 core are also -// available under terms different than the General Public License. (e.g. they -// do not require you to accompany any image (FPGA or ASIC) using the JESD204 -// core with any corresponding source code.) For these alternate terms you must -// purchase a license from Analog Devices Technology Licensing Office. Users -// interested in such a license should contact jesd204-licensing@analog.com for -// more information. This commercial license is sub-licensable (if you purchase -// chips from Analog Devices, incorporate them into your PCB level product, and -// purchase a JESD204 license, end users of your product will also have a -// license to use this core in a commercial setting without releasing their -// source code). -// -// In addition, we kindly ask you to acknowledge ADI in any program, application -// or publication in which you use this JESD204 HDL core. (You are not required -// to do so; it is up to your common sense to decide whether you want to comply -// with this request or not.) For general publications, we suggest referencing : -// “The design and implementation of the JESD204 HDL Core used in this project -// is copyright © 2016-2017, Analog Devices, Inc.” -// +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** `timescale 1ns / 100ps @@ -117,10 +80,10 @@ module jesd204_rx_fec_lfsr #( // Shift register input is output of previous shift register value, // or load value if load enabled - always @(posedge clk) begin + always @(posedge clk) begin if(rst) begin shift_reg_in_start <= RESET_VAL; - end else begin + end else begin if(load_en) begin shift_reg_in_start <= load_data; end else if(shift_en) begin diff --git a/library/jesd204/jesd204_tx/jesd204_fec_encode.sv b/library/jesd204/jesd204_tx/jesd204_fec_encode.sv index 054d70bf001..5e67aa753d9 100755 --- a/library/jesd204/jesd204_tx/jesd204_fec_encode.sv +++ b/library/jesd204/jesd204_tx/jesd204_fec_encode.sv @@ -1,47 +1,9 @@ -// -// The ADI JESD204 Core is released under the following license, which is -// different than all other HDL cores in this repository. -// -// Please read this, and understand the freedoms and responsibilities you have -// by using this source code/core. -// -// The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc. -// -// This core is free software, you can use run, copy, study, change, ask -// questions about and improve this core. Distribution of source, or resulting -// binaries (including those inside an FPGA or ASIC) require you to release the -// source of the entire project (excluding the system libraries provide by the -// tools/compiler/FPGA vendor). These are the terms of the GNU General Public -// License version 2 as published by the Free Software Foundation. -// -// This core is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -// A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License version 2 -// along with this source code, and binary. If not, see -// . -// -// Commercial licenses (with commercial support) of this JESD204 core are also -// available under terms different than the General Public License. (e.g. they -// do not require you to accompany any image (FPGA or ASIC) using the JESD204 -// core with any corresponding source code.) For these alternate terms you must -// purchase a license from Analog Devices Technology Licensing Office. Users -// interested in such a license should contact jesd204-licensing@analog.com for -// more information. This commercial license is sub-licensable (if you purchase -// chips from Analog Devices, incorporate them into your PCB level product, and -// purchase a JESD204 license, end users of your product will also have a -// license to use this core in a commercial setting without releasing their -// source code). -// -// In addition, we kindly ask you to acknowledge ADI in any program, application -// or publication in which you use this JESD204 HDL core. (You are not required -// to do so; it is up to your common sense to decide whether you want to comply -// with this request or not.) For general publications, we suggest referencing : -// “The design and implementation of the JESD204 HDL Core used in this project -// is copyright © 2016-2017, Analog Devices, Inc.” -// - +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** `timescale 1ns / 100ps diff --git a/library/jesd204/jesd204_tx/jesd204_tx.xdc b/library/jesd204/jesd204_tx/jesd204_tx.xdc index eacdf94b8bc..fa0f47ceb09 100755 --- a/library/jesd204/jesd204_tx/jesd204_tx.xdc +++ b/library/jesd204/jesd204_tx/jesd204_tx.xdc @@ -1,2 +1,7 @@ +############################################################################### +## Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +# SPDX short identifier: ADIBSD +############################################################################### + set_false_path -through [get_ports {cfg_*}] -set_false_path -through [get_ports {core_cfg_*}] \ No newline at end of file +set_false_path -through [get_ports {core_cfg_*}] diff --git a/library/jesd204/jesd204_tx/jesd204_tx_hw.tcl b/library/jesd204/jesd204_tx/jesd204_tx_hw.tcl index fd310f0ff07..b0a90fe69d7 100644 --- a/library/jesd204/jesd204_tx/jesd204_tx_hw.tcl +++ b/library/jesd204/jesd204_tx/jesd204_tx_hw.tcl @@ -59,6 +59,11 @@ set_parameter_property NUM_OUTPUT_PIPELINE DISPLAY_NAME "Number of output pipeli set_parameter_property NUM_OUTPUT_PIPELINE ALLOWED_RANGES 0:3 set_parameter_property NUM_OUTPUT_PIPELINE HDL_PARAMETER true +add_parameter NUM_INPUT_PIPELINE INTEGER 0 +set_parameter_property NUM_INPUT_PIPELINE DISPLAY_NAME "Number of input pipeline stages" +set_parameter_property NUM_INPUT_PIPELINE ALLOWED_RANGES 0:3 +set_parameter_property NUM_INPUT_PIPELINE HDL_PARAMETER true + add_parameter ASYNC_CLK BOOLEAN false set_parameter_property ASYNC_CLK DISPLAY_NAME "Link and device clock asynchronous" set_parameter_property ASYNC_CLK HDL_PARAMETER true diff --git a/library/jesd204/tb/sim_jesd204_fec b/library/jesd204/tb/sim_jesd204_fec new file mode 100755 index 00000000000..c8dc45c041a --- /dev/null +++ b/library/jesd204/tb/sim_jesd204_fec @@ -0,0 +1,13 @@ +#!/bin/bash + +export SIMULATOR=modelsim + +SOURCE="tb_link_layer_fec.sv" +SOURCE+=" ../jesd204_common/lfsr_input.sv" +SOURCE+=" ../../common/ad_mem_dist.v" +SOURCE+=" ../jesd204_tx/jesd204_fec_encode.sv" +SOURCE+=" ../jesd204_rx/jesd204_rx_fec_lfsr.sv" +SOURCE+=" ../jesd204_rx/jesd204_fec_decode.sv" + +cd `dirname $0` +source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/sim_jesd204_fec.sh b/library/jesd204/tb/sim_jesd204_fec.sh deleted file mode 100755 index ccbf8dc3f65..00000000000 --- a/library/jesd204/tb/sim_jesd204_fec.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# module load xlm - -xmvlog -sv ../jesd204_common/lfsr_input.sv -xmvlog ../../../ad_common/fpga_src/ad_mem_dist.v -xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv -xmvlog -sv ../jesd204_rx/jesd204_rx_fec_lfsr.sv -xmvlog -sv ../jesd204_rx/jesd204_fec_decode.sv -xmvlog -sv tb_link_layer_fec.v -xmelab -LICQUEUE -access +rwc -timescale 1ns/1ns tb_link_layer_fec - -if [ "$#" -ne 1 ]; then - xmsim -gui tb_link_layer_fec & -fi - diff --git a/library/jesd204/tb/sim_jesd204_fec_encode b/library/jesd204/tb/sim_jesd204_fec_encode new file mode 100755 index 00000000000..3fd9ed6e9b6 --- /dev/null +++ b/library/jesd204/tb/sim_jesd204_fec_encode @@ -0,0 +1,10 @@ +#!/bin/bash + +export SIMULATOR=modelsim + +SOURCE="tb_jesd204_fec_encode.sv" +SOURCE+=" ../jesd204_common/lfsr_input.sv" +SOURCE+=" ../jesd204_tx/jesd204_fec_encode.sv" + +cd `dirname $0` +source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/sim_jesd204_fec_encode.sh b/library/jesd204/tb/sim_jesd204_fec_encode.sh deleted file mode 100755 index baa36224f42..00000000000 --- a/library/jesd204/tb/sim_jesd204_fec_encode.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# module load xlm - -xmvlog -sv ../jesd204_common/lfsr_input.sv -xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv -xmvlog -sv tb_jesd204_fec_encode.sv -xmelab -access +rwc -timescale 1ns/1ns tb_jesd204_fec_encode - -if [ "$#" -ne 1 ]; then - xmsim -gui tb_jesd204_fec_encode & -fi diff --git a/library/jesd204/tb/sim_lfsr_input b/library/jesd204/tb/sim_lfsr_input new file mode 100755 index 00000000000..8330f08bc9b --- /dev/null +++ b/library/jesd204/tb/sim_lfsr_input @@ -0,0 +1,9 @@ +#!/bin/bash + +export SIMULATOR=modelsim + +SOURCE="tb_lfsr_input.sv" +SOURCE+=" ../jesd204_common/lfsr_input.sv" + +cd `dirname $0` +source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/sim_lfsr_input.sh b/library/jesd204/tb/sim_lfsr_input.sh deleted file mode 100755 index 0227481e77e..00000000000 --- a/library/jesd204/tb/sim_lfsr_input.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# module load xlm - -xmvlog -sv ../jesd204_common/lfsr_input.sv -xmvlog -sv tb_lfsr_input.sv -xmelab -access +rwc -timescale 1ns/1ns tb_lfsr_input - -if [ "$#" -ne 1 ]; then - xmsim -gui tb_lfsr_input & -fi diff --git a/library/jesd204/tb/sim_link_layer_fec b/library/jesd204/tb/sim_link_layer_fec new file mode 100755 index 00000000000..896fb2c0902 --- /dev/null +++ b/library/jesd204/tb/sim_link_layer_fec @@ -0,0 +1,48 @@ +#!/bin/bash + +export SIMULATOR=modelsim + +SOURCE="tb_link_layer_fec.sv" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem_dist.v" +SOURCE+=" ../../common/util_pipeline_stage.v" + +SOURCE+=" ../jesd204_common/jesd204_lmfc.v" +SOURCE+=" ../jesd204_common/jesd204_scrambler.v" +SOURCE+=" ../jesd204_common/jesd204_scrambler_64b.v" +SOURCE+=" ../jesd204_common/jesd204_crc12.v" +SOURCE+=" ../jesd204_common/jesd204_frame_mark.v" +SOURCE+=" ../jesd204_common/jesd204_frame_align_replace.v" + +SOURCE+=" ../jesd204_common/lfsr_input.sv" +SOURCE+=" ../jesd204_tx/jesd204_fec_encode.sv" +SOURCE+=" ../jesd204_tx/jesd204_tx_lane.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_lane_64b.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_gearbox.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_header.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_ctrl.v" +SOURCE+=" ../jesd204_tx/jesd204_tx.v" + +SOURCE+=" ../jesd204_rx/jesd204_rx_fec_lfsr.sv" +SOURCE+=" ../jesd204_rx/jesd204_fec_decode.sv" +SOURCE+=" ../jesd204_rx/jesd204_rx_lane.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_lane_64b.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_header.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_cgs.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl_64b.v" +SOURCE+=" ../jesd204_rx/elastic_buffer.v" +SOURCE+=" ../jesd204_rx/error_monitor.v" +SOURCE+=" ../jesd204_rx/jesd204_ilas_monitor.v" +SOURCE+=" ../jesd204_rx/align_mux.v" +SOURCE+=" ../jesd204_rx/jesd204_lane_latency_monitor.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_frame_align.v" +SOURCE+=" ../jesd204_rx/jesd204_rx.v" + +SOURCE+=" ../jesd204_rx_static_config/jesd204_rx_static_config.v" +SOURCE+=" ../jesd204_tx_static_config/jesd204_tx_static_config.v" +SOURCE+=" ../jesd204_tx_static_config/jesd204_ilas_cfg_static.v" + +cd `dirname $0` +source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/sim_link_layer_fec.sh b/library/jesd204/tb/sim_link_layer_fec.sh deleted file mode 100755 index 85d12646bb3..00000000000 --- a/library/jesd204/tb/sim_link_layer_fec.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -# module load xlm - -xmvlog ../../../util_cdc/fpga_src/sync_bits.v -xmvlog ../../../util_cdc/fpga_src/sync_event.v - -xmvlog ../jesd204_common/jesd204_lmfc.v -xmvlog ../jesd204_common/jesd204_scrambler.v -xmvlog ../jesd204_common/jesd204_scrambler_64b.v -xmvlog ../jesd204_common/jesd204_crc12.v -xmvlog ../jesd204_common/jesd204_frame_mark.v -xmvlog ../jesd204_common/jesd204_frame_align_replace.v -xmvlog ../jesd204_common/pipeline_stage.v - -xmvlog -sv ../jesd204_common/lfsr_input.sv -xmvlog -sv ../jesd204_tx/jesd204_fec_encode.sv -xmvlog ../jesd204_tx/jesd204_tx_lane.v -xmvlog ../jesd204_tx/jesd204_tx_lane_64b.v -xmvlog ../jesd204_tx/jesd204_tx_gearbox.v -xmvlog ../jesd204_tx/jesd204_tx_header.v -xmvlog ../jesd204_tx/jesd204_tx_ctrl.v -xmvlog ../jesd204_tx/jesd204_tx.v - -xmvlog ../../../ad_common/fpga_src/ad_mem_dist.v -xmvlog -sv ../jesd204_rx/jesd204_rx_fec_lfsr.sv -xmvlog -sv ../jesd204_rx/jesd204_fec_decode.sv -xmvlog ../jesd204_rx/jesd204_rx_lane.v -xmvlog ../jesd204_rx/jesd204_rx_lane_64b.v -xmvlog ../jesd204_rx/jesd204_rx_header.v -xmvlog ../jesd204_rx/jesd204_rx_cgs.v -xmvlog ../jesd204_rx/jesd204_rx_ctrl.v -xmvlog ../jesd204_rx/jesd204_rx_ctrl_64b.v -xmvlog ../jesd204_rx/elastic_buffer.v -xmvlog ../jesd204_rx/error_monitor.v -xmvlog ../jesd204_rx/jesd204_ilas_monitor.v -xmvlog ../jesd204_rx/align_mux.v -xmvlog ../jesd204_rx/jesd204_lane_latency_monitor.v -xmvlog ../jesd204_rx/jesd204_rx_frame_align.v -xmvlog ../jesd204_rx/jesd204_rx.v - -xmvlog ../jesd204_rx_static_config/jesd204_rx_static_config.v -xmvlog ../jesd204_tx_static_config/jesd204_tx_static_config.v -xmvlog ../jesd204_tx_static_config/jesd204_ilas_cfg_static.v - -xmvlog -sv tb_link_layer_fec.sv -xmelab -LICQUEUE -access +rwc -timescale 1ns/1ns tb_link_layer_fec - -if [ "$#" -ne 1 ]; then - xmsim -LICQUEUE -gui tb_link_layer_fec & -fi diff --git a/library/jesd204/tb/tb_jesd204_fec.sv b/library/jesd204/tb/tb_jesd204_fec.sv index 1e8aa6b322c..08c3395427f 100755 --- a/library/jesd204/tb/tb_jesd204_fec.sv +++ b/library/jesd204/tb/tb_jesd204_fec.sv @@ -1,3 +1,10 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** + `timescale 1ns / 100ps `default_nettype none @@ -145,7 +152,6 @@ module tb_jesd204_fec; .data_in (decode_data_in) ); - endmodule `default_nettype wire diff --git a/library/jesd204/tb/tb_jesd204_fec_encode.v b/library/jesd204/tb/tb_jesd204_fec_encode.sv similarity index 80% rename from library/jesd204/tb/tb_jesd204_fec_encode.v rename to library/jesd204/tb/tb_jesd204_fec_encode.sv index bf4352e121b..6180579e57b 100755 --- a/library/jesd204/tb/tb_jesd204_fec_encode.v +++ b/library/jesd204/tb/tb_jesd204_fec_encode.sv @@ -1,3 +1,10 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** + `timescale 1ns / 100ps `default_nettype none diff --git a/library/jesd204/tb/tb_lfsr_input.sv b/library/jesd204/tb/tb_lfsr_input.sv index f7390c3e7e8..3ac5464d13b 100755 --- a/library/jesd204/tb/tb_lfsr_input.sv +++ b/library/jesd204/tb/tb_lfsr_input.sv @@ -1,7 +1,13 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** + `timescale 1ns / 100ps `default_nettype none - module tb_lfsr_input; localparam LFSR_WIDTH = 26; @@ -44,7 +50,7 @@ module tb_lfsr_input; - + initial begin for(ii = 0; ii < INPUT_DATA_WIDTH; ii = ii + 1) begin diff --git a/library/jesd204/tb/tb_link_layer_fec.sv b/library/jesd204/tb/tb_link_layer_fec.sv index a0adcb775e8..d3f55168fa2 100755 --- a/library/jesd204/tb/tb_link_layer_fec.sv +++ b/library/jesd204/tb/tb_link_layer_fec.sv @@ -1,3 +1,11 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2025 Analog Devices, Inc. All rights reserved. +// SPDX short identifier: ADIJESD204 +// *************************************************************************** +// *************************************************************************** + + `timescale 1ns / 100ps `default_nettype none From 41bafd994a1bd9063de38a912d80e294f1968c22 Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Tue, 5 Aug 2025 17:39:39 +0300 Subject: [PATCH 07/11] library: jesd204: axi_jesd204: Bump core version Signed-off-by: Bogdan Luncan --- library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v | 12 ++++++------ library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v index e1dd545180a..df8189e1922 100755 --- a/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v +++ b/library/jesd204/axi_jesd204_rx/axi_jesd204_rx.v @@ -91,11 +91,11 @@ module axi_jesd204_rx #( input [31:0] status_synth_params2 ); - localparam PCORE_VERSION = 32'h00010761; // 1.07.a + localparam PCORE_VERSION = 32'h00010861; // 1.08.a localparam PCORE_MAGIC = 32'h32303452; // 204R - + localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2; - + /* Register interface signals */ reg [31:0] up_rdata = 'h0; reg up_wack = 1'b0; @@ -246,9 +246,9 @@ module axi_jesd204_rx #( jesd204_up_sysref #( .DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2) - ) i_up_sysref ( - .up_clk(s_axi_aclk), - .up_reset(up_reset), + ) i_up_sysref ( + .up_clk(s_axi_aclk), + .up_reset(up_reset), .core_clk(core_clk), .device_clk(device_clk), diff --git a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v index 9f10941a504..cddae79fda7 100755 --- a/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v +++ b/library/jesd204/axi_jesd204_tx/axi_jesd204_tx.v @@ -83,7 +83,7 @@ module axi_jesd204_tx #( input [31:0] status_synth_params2 ); - localparam PCORE_VERSION = 32'h00010661; // 1.06.a + localparam PCORE_VERSION = 32'h00010761; // 1.07.a localparam PCORE_MAGIC = 32'h32303454; // 204T localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2; From bcd03537d7f89d88671dd7a7bc2574abaa05960b Mon Sep 17 00:00:00 2001 From: bluncan Date: Wed, 6 Aug 2025 12:43:52 +0300 Subject: [PATCH 08/11] library: jesd204: jesd204_fec_decode: Register ad_mem output Signed-off-by: bluncan --- library/jesd204/jesd204_rx/jesd204_fec_decode.sv | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/jesd204/jesd204_rx/jesd204_fec_decode.sv b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv index 59b9c4f7200..2ad822c6353 100755 --- a/library/jesd204/jesd204_rx/jesd204_fec_decode.sv +++ b/library/jesd204/jesd204_rx/jesd204_fec_decode.sv @@ -54,7 +54,6 @@ module jesd204_fec_decode #( logic [BUFFER_ADDR_WIDTH-1:0] buf_rd_addr; logic [DATA_WIDTH-1:0] buf_wr_data; logic [DATA_WIDTH-1:0] buf_rd_data; - // logic [DATA_WIDTH-1:0] buf_rd_data_d; logic [3:1] eomb_d; logic data_in_en; logic fec_in_en; @@ -222,7 +221,6 @@ module jesd204_fec_decode #( always_ff @(posedge clk) begin error_syndrome_next_d <= error_syndrome_next; - // buf_rd_data_d <= buf_rd_data; end // Error is trapped if the MSb of the syndrome is 1 and bits 16:0 of the syndrome are 0 From 6bba191ba5af597cd98740b2809aa61ca2fe71ba Mon Sep 17 00:00:00 2001 From: bluncan Date: Wed, 6 Aug 2025 12:45:07 +0300 Subject: [PATCH 09/11] library: jesd204: tb: Make tb work with modelsim Signed-off-by: bluncan --- library/jesd204/tb/sim_jesd204_fec | 13 ----- library/jesd204/tb/tb_jesd204_fec | 48 +++++++++++++++++++ library/jesd204/tb/tb_jesd204_fec.sv | 4 +- ...sd204_fec_encode => tb_jesd204_fec_encode} | 0 library/jesd204/tb/tb_jesd204_fec_encode.sv | 4 +- .../tb/{sim_lfsr_input => tb_lfsr_input} | 0 library/jesd204/tb/tb_lfsr_input.sv | 5 +- .../{sim_link_layer_fec => tb_link_layer_fec} | 0 library/jesd204/tb/tb_link_layer_fec.sv | 7 +-- 9 files changed, 61 insertions(+), 20 deletions(-) delete mode 100755 library/jesd204/tb/sim_jesd204_fec create mode 100755 library/jesd204/tb/tb_jesd204_fec rename library/jesd204/tb/{sim_jesd204_fec_encode => tb_jesd204_fec_encode} (100%) rename library/jesd204/tb/{sim_lfsr_input => tb_lfsr_input} (100%) rename library/jesd204/tb/{sim_link_layer_fec => tb_link_layer_fec} (100%) diff --git a/library/jesd204/tb/sim_jesd204_fec b/library/jesd204/tb/sim_jesd204_fec deleted file mode 100755 index c8dc45c041a..00000000000 --- a/library/jesd204/tb/sim_jesd204_fec +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -export SIMULATOR=modelsim - -SOURCE="tb_link_layer_fec.sv" -SOURCE+=" ../jesd204_common/lfsr_input.sv" -SOURCE+=" ../../common/ad_mem_dist.v" -SOURCE+=" ../jesd204_tx/jesd204_fec_encode.sv" -SOURCE+=" ../jesd204_rx/jesd204_rx_fec_lfsr.sv" -SOURCE+=" ../jesd204_rx/jesd204_fec_decode.sv" - -cd `dirname $0` -source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/tb_jesd204_fec b/library/jesd204/tb/tb_jesd204_fec new file mode 100755 index 00000000000..25595b5263c --- /dev/null +++ b/library/jesd204/tb/tb_jesd204_fec @@ -0,0 +1,48 @@ +#!/bin/bash + +export SIMULATOR=modelsim + +SOURCE="tb_jesd204_fec.sv" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem_dist.v" +SOURCE+=" ../../common/util_pipeline_stage.v" + +SOURCE+=" ../jesd204_common/jesd204_lmfc.v" +SOURCE+=" ../jesd204_common/jesd204_scrambler.v" +SOURCE+=" ../jesd204_common/jesd204_scrambler_64b.v" +SOURCE+=" ../jesd204_common/jesd204_crc12.v" +SOURCE+=" ../jesd204_common/jesd204_frame_mark.v" +SOURCE+=" ../jesd204_common/jesd204_frame_align_replace.v" + +SOURCE+=" ../jesd204_common/lfsr_input.sv" +SOURCE+=" ../jesd204_tx/jesd204_fec_encode.sv" +SOURCE+=" ../jesd204_tx/jesd204_tx_lane.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_lane_64b.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_gearbox.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_header.v" +SOURCE+=" ../jesd204_tx/jesd204_tx_ctrl.v" +SOURCE+=" ../jesd204_tx/jesd204_tx.v" + +SOURCE+=" ../jesd204_rx/jesd204_rx_fec_lfsr.sv" +SOURCE+=" ../jesd204_rx/jesd204_fec_decode.sv" +SOURCE+=" ../jesd204_rx/jesd204_rx_lane.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_lane_64b.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_header.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_cgs.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl_64b.v" +SOURCE+=" ../jesd204_rx/elastic_buffer.v" +SOURCE+=" ../jesd204_rx/error_monitor.v" +SOURCE+=" ../jesd204_rx/jesd204_ilas_monitor.v" +SOURCE+=" ../jesd204_rx/align_mux.v" +SOURCE+=" ../jesd204_rx/jesd204_lane_latency_monitor.v" +SOURCE+=" ../jesd204_rx/jesd204_rx_frame_align.v" +SOURCE+=" ../jesd204_rx/jesd204_rx.v" + +SOURCE+=" ../jesd204_rx_static_config/jesd204_rx_static_config.v" +SOURCE+=" ../jesd204_tx_static_config/jesd204_tx_static_config.v" +SOURCE+=" ../jesd204_tx_static_config/jesd204_ilas_cfg_static.v" + +cd `dirname $0` +source ../../common/tb/run_tb.sh diff --git a/library/jesd204/tb/tb_jesd204_fec.sv b/library/jesd204/tb/tb_jesd204_fec.sv index 08c3395427f..7d5c1188a08 100755 --- a/library/jesd204/tb/tb_jesd204_fec.sv +++ b/library/jesd204/tb/tb_jesd204_fec.sv @@ -24,13 +24,15 @@ module tb_jesd204_fec; localparam ERROR_BITS = 64'h1FF000; // Bits of decoder input data to corrupt localparam FEC_ERROR_BITS = '0; // {1'b1, 25'b0}; + parameter VCD_FILE = {"tb_jesd204_fec.vcd"}; + `include "tb_base.v" + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; logic [INPUT_DATA_WIDTH-1:0] data; logic [FEC_WIDTH-1:0] fec; logic [FEC_WIDTH-1:0] fec_saved; logic [FEC_WIDTH-1:0] decode_fec_in; - reg clk = 1'b0; logic rst; logic fec_in_valid; logic shift_en; diff --git a/library/jesd204/tb/sim_jesd204_fec_encode b/library/jesd204/tb/tb_jesd204_fec_encode similarity index 100% rename from library/jesd204/tb/sim_jesd204_fec_encode rename to library/jesd204/tb/tb_jesd204_fec_encode diff --git a/library/jesd204/tb/tb_jesd204_fec_encode.sv b/library/jesd204/tb/tb_jesd204_fec_encode.sv index 6180579e57b..253bd8590ba 100755 --- a/library/jesd204/tb/tb_jesd204_fec_encode.sv +++ b/library/jesd204/tb/tb_jesd204_fec_encode.sv @@ -18,11 +18,13 @@ module tb_jesd204_fec_encode; localparam INPUT_DATA_WIDTH = 2048; localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = {1'b1, 2047'b0}; + parameter VCD_FILE = {"tb_jesd204_fec_encode.vcd"}; + `include "tb_base.v" + logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; logic [DATA_WIDTH-1:0] data; logic [FEC_WIDTH-1:0] fec; - reg clk = 1'b0; logic rst; logic shift_en; logic [DATA_WIDTH-1:0] data_in; diff --git a/library/jesd204/tb/sim_lfsr_input b/library/jesd204/tb/tb_lfsr_input similarity index 100% rename from library/jesd204/tb/sim_lfsr_input rename to library/jesd204/tb/tb_lfsr_input diff --git a/library/jesd204/tb/tb_lfsr_input.sv b/library/jesd204/tb/tb_lfsr_input.sv index 3ac5464d13b..362d63776b1 100755 --- a/library/jesd204/tb/tb_lfsr_input.sv +++ b/library/jesd204/tb/tb_lfsr_input.sv @@ -9,12 +9,14 @@ `default_nettype none module tb_lfsr_input; - localparam LFSR_WIDTH = 26; localparam [LFSR_WIDTH:1] RESET_VAL = {LFSR_WIDTH{1'b0}}; localparam [LFSR_WIDTH:1] LFSR_POLYNOMIAL = 26'h2210110; localparam MAX_SHIFT_CNT = 64; + parameter VCD_FILE = {"tb_lfsr_input.vcd"}; + `include "tb_base.v" + // localparam INPUT_DATA_WIDTH = 64; // localparam logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE = 64'h8001020305050423; localparam INPUT_DATA_WIDTH = 2048; @@ -25,7 +27,6 @@ module tb_lfsr_input; logic [MAX_SHIFT_CNT-1:0] data_out; logic [LFSR_WIDTH:1] shift_reg; - reg clk = 1'b0; logic rst; logic shift_en; logic [$clog2(MAX_SHIFT_CNT)-1:0] shift_cnt; diff --git a/library/jesd204/tb/sim_link_layer_fec b/library/jesd204/tb/tb_link_layer_fec similarity index 100% rename from library/jesd204/tb/sim_link_layer_fec rename to library/jesd204/tb/tb_link_layer_fec diff --git a/library/jesd204/tb/tb_link_layer_fec.sv b/library/jesd204/tb/tb_link_layer_fec.sv index d3f55168fa2..030a1bee082 100755 --- a/library/jesd204/tb/tb_link_layer_fec.sv +++ b/library/jesd204/tb/tb_link_layer_fec.sv @@ -10,7 +10,6 @@ `default_nettype none module tb_link_layer_fec; - localparam NUM_LANES=2; localparam NUM_LINKS=1; localparam SCR = 0; @@ -29,8 +28,9 @@ module tb_link_layer_fec; // localparam NEXT_ERROR_BITS = 64'h0000000000000000; localparam REPORT_GOOD_DATA = 1'b1; - reg clk = 1'b0; - reg sysref = 1'b0; + parameter VCD_FILE = {"tb_link_layer_fec.vcd"}; + `include "tb_base.v" + logic rst; logic [INPUT_DATA_WIDTH-1:0] DATA_VALUE_REVERSED; logic [INPUT_DATA_WIDTH-1:0] data; @@ -238,6 +238,7 @@ module tb_link_layer_fec; cur_tx_data = tx_data_q.pop_front(); if(cur_tx_data !== rx_data) begin $error("RX Cycle: %d Data mismatch. Expected: %X Observed: %X", rx_cycle_cnt, cur_tx_data, rx_data); + failed = 1'b1; end else if(REPORT_GOOD_DATA) begin $display("RX Cycle: %d Good data:%X", rx_cycle_cnt, cur_tx_data); end From e0a34eb7d5c9f66075952c9871138227596dd01c Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Thu, 7 Aug 2025 16:29:41 +0300 Subject: [PATCH 10/11] library: jesd204: Add missing .v dependencies Signed-off-by: Bogdan Luncan --- library/jesd204/jesd204_rx/Makefile | 4 ++++ library/jesd204/jesd204_rx/jesd204_rx_ip.tcl | 4 ++++ library/jesd204/jesd204_tx/Makefile | 3 +++ library/jesd204/jesd204_tx/jesd204_tx_ip.tcl | 3 +++ 4 files changed, 14 insertions(+) diff --git a/library/jesd204/jesd204_rx/Makefile b/library/jesd204/jesd204_rx/Makefile index da539caaa91..ac19e1ca048 100644 --- a/library/jesd204/jesd204_rx/Makefile +++ b/library/jesd204/jesd204_rx/Makefile @@ -8,6 +8,7 @@ LIBRARY_NAME := jesd204_rx GENERIC_DEPS += ../../common/ad_pack.v GENERIC_DEPS += ../../common/ad_upack.v +GENERIC_DEPS += ../../common/ad_mem_dist.v GENERIC_DEPS += align_mux.v GENERIC_DEPS += elastic_buffer.v GENERIC_DEPS += jesd204_ilas_monitor.v @@ -18,6 +19,9 @@ GENERIC_DEPS += jesd204_rx_ctrl.v GENERIC_DEPS += jesd204_rx_frame_align.v GENERIC_DEPS += jesd204_rx_lane.v GENERIC_DEPS += ../jesd204_common/jesd204_crc12.v +GENERIC_DEPS += ../jesd204_common/lfsr_input.sv +GENERIC_DEPS += jesd204_rx_fec_lfsr.sv +GENERIC_DEPS += jesd204_fec_decode.sv GENERIC_DEPS += error_monitor.v XILINX_DEPS += bd/bd.tcl diff --git a/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl b/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl index 26147f6e16c..9768bc1bbff 100755 --- a/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl +++ b/library/jesd204/jesd204_rx/jesd204_rx_ip.tcl @@ -25,10 +25,14 @@ adi_ip_files jesd204_rx [list \ "jesd204_rx_constr.ttcl" \ "jesd204_rx_ooc.ttcl" \ "jesd204_rx.v" \ + "jesd204_fec_decode.sv" \ + "jesd204_rx_fec_lfsr.sv" \ + "../jesd204_common/lfsr_input.sv" \ "jesd204_rx.xdc" \ "../../common/ad_pack.v" \ "../../common/ad_upack.v" \ "../../common/util_pipeline_stage.v" \ + "../../common/ad_mem_dist.v" \ "bd/bd.tcl" ] diff --git a/library/jesd204/jesd204_tx/Makefile b/library/jesd204/jesd204_tx/Makefile index 6497197ebe0..eb596802980 100644 --- a/library/jesd204/jesd204_tx/Makefile +++ b/library/jesd204/jesd204_tx/Makefile @@ -8,10 +8,13 @@ LIBRARY_NAME := jesd204_tx GENERIC_DEPS += ../../common/ad_pack.v GENERIC_DEPS += ../../common/ad_upack.v +GENERIC_DEPS += ../../common/ad_mem_dist.v GENERIC_DEPS += jesd204_tx.v GENERIC_DEPS += jesd204_tx_ctrl.v GENERIC_DEPS += jesd204_tx_gearbox.v GENERIC_DEPS += jesd204_tx_lane.v +GENERIC_DEPS += jesd204_fec_encode.sv +GENERIC_DEPS += ../jesd204_common/lfsr_input.sv XILINX_DEPS += bd/bd.tcl XILINX_DEPS += jesd204_tx_constr.ttcl diff --git a/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl b/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl index 59c3c83d52b..5ee96ab0135 100644 --- a/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl +++ b/library/jesd204/jesd204_tx/jesd204_tx_ip.tcl @@ -15,12 +15,15 @@ adi_ip_files jesd204_tx [list \ "jesd204_tx_header.v" \ "jesd204_tx_gearbox.v" \ "jesd204_tx_ctrl.v" \ + "jesd204_fec_encode.sv" \ + "../jesd204_common/lfsr_input.sv" \ "jesd204_tx_constr.ttcl" \ "jesd204_tx_ooc.ttcl" \ "jesd204_tx.xdc" \ "../../common/ad_pack.v" \ "../../common/ad_upack.v" \ "../../common/util_pipeline_stage.v" \ + "../../common/ad_mem_dist.v" \ "jesd204_tx.v" \ "bd/bd.tcl" ] From 3513345b0ead0018e8f28c91ec7682930a954cb3 Mon Sep 17 00:00:00 2001 From: Bogdan Luncan Date: Thu, 7 Aug 2025 16:30:26 +0300 Subject: [PATCH 11/11] library: jesd204: ad_ip_jesd204_tpl_adc: Add optional pipeline stage inside deframer Signed-off-by: Bogdan Luncan --- .../ad_ip_jesd204_tpl_adc.v | 8 +++-- .../ad_ip_jesd204_tpl_adc_core.v | 8 +++-- .../ad_ip_jesd204_tpl_adc_deframer.v | 29 ++++++++++++++++--- .../ad_ip_jesd204_tpl_adc_hw.tcl | 8 ++++- .../ad_ip_jesd204_tpl_adc_ip.tcl | 4 ++- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v index 6240701b41f..a08d39cc6c5 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -52,7 +52,8 @@ module ad_ip_jesd204_tpl_adc #( parameter TWOS_COMPLEMENT = 1, parameter EXT_SYNC = 0, parameter PN7_ENABLE = 1, - parameter PN15_ENABLE = 1 + parameter PN15_ENABLE = 1, + parameter NUM_PIPELINE_STAGES = 0 ) ( // jesd interface @@ -209,7 +210,8 @@ module ad_ip_jesd204_tpl_adc #( .DMA_BITS_PER_SAMPLE (DMA_BITS_PER_SAMPLE), .EXT_SYNC (EXT_SYNC), .PN7_ENABLE (PN7_ENABLE), - .PN15_ENABLE(PN15_ENABLE) + .PN15_ENABLE(PN15_ENABLE), + .NUM_PIPELINE_STAGES (NUM_PIPELINE_STAGES) ) i_core ( .clk (link_clk), diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v index cc0004acebd..845a18990da 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -50,7 +50,8 @@ module ad_ip_jesd204_tpl_adc_core #( parameter TWOS_COMPLEMENT = 1, parameter EXT_SYNC = 0, parameter PN7_ENABLE = 1, - parameter PN15_ENABLE = 1 + parameter PN15_ENABLE = 1, + parameter NUM_PIPELINE_STAGES = 0 ) ( input clk, @@ -119,7 +120,8 @@ module ad_ip_jesd204_tpl_adc_core #( .OCTETS_PER_BEAT (OCTETS_PER_BEAT), .EN_FRAME_ALIGN (EN_FRAME_ALIGN), .LINK_DATA_WIDTH (LINK_DATA_WIDTH), - .ADC_DATA_WIDTH (ADC_DATA_WIDTH) + .ADC_DATA_WIDTH (ADC_DATA_WIDTH), + .NUM_PIPELINE_STAGES (NUM_PIPELINE_STAGES) ) i_deframer ( .clk (clk), .link_sof (link_sof), diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v index afdeccfea5a..bd58876b948 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -43,6 +43,7 @@ module ad_ip_jesd204_tpl_adc_deframer #( parameter SAMPLES_PER_FRAME = 1, parameter OCTETS_PER_BEAT = 8, parameter EN_FRAME_ALIGN = 0, + parameter NUM_PIPELINE_STAGES = 0, parameter LINK_DATA_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES, parameter ADC_DATA_WIDTH = LINK_DATA_WIDTH * CONVERTER_RESOLUTION / BITS_PER_SAMPLE ) ( @@ -65,11 +66,31 @@ module ad_ip_jesd204_tpl_adc_deframer #( NUM_CHANNELS / NUM_LANES; localparam FRAMES_PER_BEAT = OCTETS_PER_BEAT * 8 / BITS_PER_LANE_PER_FRAME; + wire [LINK_DATA_WIDTH-1:0] link_data_r; + wire [LINK_DATA_WIDTH-1:0] frame_data_r; + wire [LINK_DATA_WIDTH-1:0] adc_data_r; + wire [LINK_DATA_WIDTH-1:0] link_data_s; wire [LINK_DATA_WIDTH-1:0] link_data_msb_s; wire [LINK_DATA_WIDTH-1:0] frame_data_s; wire [LINK_DATA_WIDTH-1:0] adc_data_msb; + util_pipeline_stage #( + .REGISTERED (NUM_PIPELINE_STAGES), + .WIDTH (3*LINK_DATA_WIDTH) + ) i_pipeline_stages ( + .clk (clk), + .in ({ + link_data_s, + frame_data_s, + adc_data_msb + }), + .out ({ + link_data_r, + frame_data_r, + adc_data_r + })); + // data multiplex genvar i; @@ -77,7 +98,7 @@ module ad_ip_jesd204_tpl_adc_deframer #( generate /* Reorder octets MSB first */ for (i = 0; i < LINK_DATA_WIDTH; i = i + 8) begin: g_adc_data - assign link_data_msb_s[i+:8] = link_data_s[LINK_DATA_WIDTH-1-i-:8]; + assign link_data_msb_s[i+:8] = link_data_r[LINK_DATA_WIDTH-1-i-:8]; end /* Slice lanes into frames */ @@ -95,7 +116,7 @@ module ad_ip_jesd204_tpl_adc_deframer #( .WORDS_PER_GROUP (NUM_CHANNELS), .WORD_WIDTH (BITS_PER_CHANNEL_PER_FRAME) ) i_frames_to_channels ( - .data_in (frame_data_s), + .data_in (frame_data_r), .data_out (adc_data_msb)); /* Reorder samples LSB first and remove tail bits */ @@ -105,7 +126,7 @@ module ad_ip_jesd204_tpl_adc_deframer #( localparam src_msb = LINK_DATA_WIDTH - 1 - i * src_w ; localparam dst_lsb = i * dst_w; - assign adc_data[dst_lsb+:dst_w] = adc_data_msb[src_msb-:dst_w]; + assign adc_data[dst_lsb+:dst_w] = adc_data_r[src_msb-:dst_w]; end endgenerate diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl index 45e0c69db18..78f577e1374 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl @@ -1,5 +1,5 @@ ############################################################################### -## Copyright (C) 2018-2022, 2024 Analog Devices, Inc. All rights reserved. +## Copyright (C) 2018-2022, 2024-2025 Analog Devices, Inc. All rights reserved. ### SPDX short identifier: ADIJESD204 ############################################################################### @@ -50,6 +50,12 @@ ad_ip_parameter OCTETS_PER_BEAT INTEGER 4 true [list \ GROUP $group \ ] +ad_ip_parameter NUM_PIPELINE_STAGES INTEGER 0 true [list \ + DISPLAY_NAME "Number of pipeline stages inside the deframer" \ + ALLOWED_RANGES {0 1 2} \ + GROUP $group \ +] + set group "JESD204 Deframer Configuration" ad_ip_parameter NUM_LANES INTEGER 1 true [list \ diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl index cb407b48abe..7b58e9ae9f7 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl @@ -1,5 +1,5 @@ ############################################################################### -## Copyright (C) 2018-2022 Analog Devices, Inc. All rights reserved. +## Copyright (C) 2018-2022, 2025 Analog Devices, Inc. All rights reserved. ### SPDX short identifier: ADIJESD204 ############################################################################### @@ -21,6 +21,7 @@ adi_ip_files ad_ip_jesd204_tpl_adc [list \ "$ad_hdl_dir/library/common/up_adc_channel.v" \ "$ad_hdl_dir/library/common/util_ext_sync.v" \ "$ad_hdl_dir/library/common/ad_xcvr_rx_if.v" \ + "$ad_hdl_dir/library/common/util_pipeline_stage.v" \ "$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \ "$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \ "$ad_hdl_dir/library/xilinx/common/up_xfer_status_constr.xdc" \ @@ -68,6 +69,7 @@ foreach {p v} { "CONVERTER_RESOLUTION" "8 11 12 14 16" \ "SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \ "OCTETS_PER_BEAT" "4 6 8 12 16 32 64" \ + "NUM_PIPELINE_STAGES" "0 1 2" \ } { \ set_property -dict [list \ "value_validation_type" "list" \