2017-05-17 17:28:50 +00:00
|
|
|
//
|
|
|
|
// 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
|
|
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
//
|
|
|
|
// 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.”
|
|
|
|
//
|
|
|
|
|
2018-08-27 07:14:54 +00:00
|
|
|
`timescale 1ns/100ps
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
module jesd204_tx #(
|
2018-03-29 09:38:34 +00:00
|
|
|
parameter NUM_LANES = 1,
|
2019-08-26 14:53:17 +00:00
|
|
|
parameter NUM_LINKS = 1,
|
2019-10-01 15:12:11 +00:00
|
|
|
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 */
|
2020-10-09 06:25:13 +00:00
|
|
|
parameter DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4,
|
2020-10-27 15:40:37 +00:00
|
|
|
parameter TPL_DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4,
|
|
|
|
parameter ENABLE_CHAR_REPLACE = 1'b0,
|
|
|
|
parameter ASYNC_CLK = 1
|
2017-05-17 17:28:50 +00:00
|
|
|
) (
|
|
|
|
input clk,
|
|
|
|
input reset,
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
input device_clk,
|
|
|
|
input device_reset,
|
|
|
|
|
2019-10-01 15:12:11 +00:00
|
|
|
output [DATA_PATH_WIDTH*8*NUM_LANES-1:0] phy_data,
|
|
|
|
output [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_charisk,
|
|
|
|
output [2*NUM_LANES-1:0] phy_header,
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
input sysref,
|
|
|
|
output lmfc_edge,
|
|
|
|
output lmfc_clk,
|
|
|
|
|
2018-03-29 09:38:34 +00:00
|
|
|
input [NUM_LINKS-1:0] sync,
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
input [TPL_DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data,
|
2017-05-17 17:28:50 +00:00
|
|
|
output tx_ready,
|
2020-10-27 15:40:37 +00:00
|
|
|
output [TPL_DATA_PATH_WIDTH-1:0] tx_eof,
|
|
|
|
output [TPL_DATA_PATH_WIDTH-1:0] tx_sof,
|
|
|
|
output [TPL_DATA_PATH_WIDTH-1:0] tx_somf,
|
|
|
|
output [TPL_DATA_PATH_WIDTH-1:0] tx_eomf,
|
2017-07-17 13:32:16 +00:00
|
|
|
input tx_valid,
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
input [NUM_LANES-1:0] cfg_lanes_disable,
|
2018-03-29 09:38:34 +00:00
|
|
|
input [NUM_LINKS-1:0] cfg_links_disable,
|
2020-01-30 22:05:13 +00:00
|
|
|
input [9:0] cfg_octets_per_multiframe,
|
2017-05-17 17:28:50 +00:00
|
|
|
input [7:0] cfg_octets_per_frame,
|
|
|
|
input cfg_continuous_cgs,
|
|
|
|
input cfg_continuous_ilas,
|
|
|
|
input cfg_skip_ilas,
|
|
|
|
input [7:0] cfg_mframes_per_ilas,
|
|
|
|
input cfg_disable_char_replacement,
|
|
|
|
input cfg_disable_scrambler,
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
input [9:0] device_cfg_octets_per_multiframe,
|
|
|
|
input [7:0] device_cfg_octets_per_frame,
|
|
|
|
input [7:0] device_cfg_beats_per_multiframe,
|
|
|
|
input [7:0] device_cfg_lmfc_offset,
|
|
|
|
input device_cfg_sysref_oneshot,
|
|
|
|
input device_cfg_sysref_disable,
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
output ilas_config_rd,
|
|
|
|
output [1:0] ilas_config_addr,
|
2020-01-30 22:05:13 +00:00
|
|
|
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data,
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
input ctrl_manual_sync_request,
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
output device_event_sysref_edge,
|
|
|
|
output device_event_sysref_alignment_error,
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2018-03-29 09:38:34 +00:00
|
|
|
output [NUM_LINKS-1:0] status_sync,
|
2020-12-03 13:59:33 +00:00
|
|
|
output [1:0] status_state,
|
|
|
|
|
|
|
|
output [31:0] status_synth_params0,
|
|
|
|
output [31:0] status_synth_params1,
|
|
|
|
output [31:0] status_synth_params2
|
2017-05-17 17:28:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
2020-01-30 22:05:13 +00:00
|
|
|
localparam MAX_OCTETS_PER_FRAME = 32;
|
2017-05-17 17:28:50 +00:00
|
|
|
localparam MAX_OCTETS_PER_MULTIFRAME =
|
|
|
|
(MAX_OCTETS_PER_FRAME * 32) > 1024 ? 1024 : (MAX_OCTETS_PER_FRAME * 32);
|
|
|
|
localparam MAX_BEATS_PER_MULTIFRAME = MAX_OCTETS_PER_MULTIFRAME / DATA_PATH_WIDTH;
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
localparam LMFC_COUNTER_WIDTH = MAX_BEATS_PER_MULTIFRAME > 256 ? 9 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 128 ? 8 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 64 ? 7 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 32 ? 6 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 16 ? 5 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 8 ? 4 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 4 ? 3 :
|
|
|
|
MAX_BEATS_PER_MULTIFRAME > 2 ? 2 : 1;
|
|
|
|
|
|
|
|
localparam DW = DATA_PATH_WIDTH * 8 * NUM_LANES;
|
2019-08-26 14:53:17 +00:00
|
|
|
localparam CW = DATA_PATH_WIDTH * NUM_LANES;
|
2019-10-01 15:12:11 +00:00
|
|
|
localparam HW = 2 * NUM_LANES;
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2019-08-26 14:53:17 +00:00
|
|
|
wire [DW-1:0] phy_data_r;
|
|
|
|
wire [CW-1:0] phy_charisk_r;
|
2019-10-01 15:12:11 +00:00
|
|
|
wire [HW-1:0] phy_header_r;
|
|
|
|
|
2020-01-30 22:05:13 +00:00
|
|
|
wire eof_gen_reset;
|
2020-09-28 14:29:47 +00:00
|
|
|
wire tx_ready_64b_next;
|
2020-01-30 22:05:13 +00:00
|
|
|
reg tx_ready_64b;
|
|
|
|
wire frame_mark_reset;
|
2020-09-28 14:29:47 +00:00
|
|
|
wire [DATA_PATH_WIDTH-1:0] tx_sof_fm;
|
|
|
|
wire [DATA_PATH_WIDTH-1:0] tx_eof_fm;
|
|
|
|
wire [DATA_PATH_WIDTH-1:0] tx_somf_fm;
|
|
|
|
wire [DATA_PATH_WIDTH-1:0] tx_eomf_fm;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_sof_fm_d1;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eof_fm_d1;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_somf_fm_d1;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d1;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_sof_fm_d2;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eof_fm_d2;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_somf_fm_d2;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d2;
|
2020-10-27 15:40:37 +00:00
|
|
|
wire lmfc_edge_synced;
|
2019-10-01 15:12:11 +00:00
|
|
|
wire lmc_edge;
|
|
|
|
wire lmc_quarter_edge;
|
|
|
|
wire eoemb;
|
2020-10-27 15:40:37 +00:00
|
|
|
wire [DATA_PATH_WIDTH*8*NUM_LANES-1:0] gearbox_data;
|
|
|
|
wire tx_ready_nx;
|
|
|
|
wire link_lmfc_edge;
|
|
|
|
wire link_lmfc_clk;
|
|
|
|
wire device_lmfc_edge;
|
|
|
|
wire device_lmfc_clk;
|
|
|
|
wire device_lmc_edge;
|
|
|
|
wire device_lmc_quarter_edge;
|
|
|
|
wire device_eoemb;
|
|
|
|
wire tx_next_mf_ready;
|
|
|
|
wire link_tx_ready;
|
|
|
|
|
|
|
|
wire [7:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe >> DPW_LOG2;
|
|
|
|
wire [7:0] device_cfg_beats_per_multiframe_s;
|
|
|
|
|
|
|
|
// If input and output widths are symmetric keep the calculation for backwards
|
|
|
|
// compatibility of the software.
|
|
|
|
assign device_cfg_beats_per_multiframe_s = (TPL_DATA_PATH_WIDTH == DATA_PATH_WIDTH) ?
|
|
|
|
device_cfg_octets_per_multiframe >> DPW_LOG2 :
|
|
|
|
device_cfg_beats_per_multiframe;
|
2019-08-26 14:53:17 +00:00
|
|
|
|
2020-01-30 22:05:13 +00:00
|
|
|
jesd204_lmfc #(
|
|
|
|
.LINK_MODE(LINK_MODE),
|
2020-10-27 15:40:37 +00:00
|
|
|
.DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH)
|
2020-01-30 22:05:13 +00:00
|
|
|
) i_lmfc (
|
2020-10-27 15:40:37 +00:00
|
|
|
.clk(device_clk),
|
|
|
|
.reset(device_reset),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
|
|
|
.cfg_lmfc_offset(device_cfg_lmfc_offset),
|
|
|
|
.cfg_beats_per_multiframe(device_cfg_beats_per_multiframe_s),
|
|
|
|
.cfg_sysref_oneshot(device_cfg_sysref_oneshot),
|
|
|
|
.cfg_sysref_disable(device_cfg_sysref_disable),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
.sysref(sysref),
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.sysref_edge(device_event_sysref_edge),
|
|
|
|
.sysref_alignment_error(device_event_sysref_alignment_error),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.lmfc_edge(device_lmfc_edge),
|
|
|
|
.lmfc_clk(device_lmfc_clk),
|
2019-10-01 15:12:11 +00:00
|
|
|
.lmfc_counter(),
|
2020-10-27 15:40:37 +00:00
|
|
|
.lmc_edge(device_lmc_edge),
|
|
|
|
.lmc_quarter_edge(device_lmc_quarter_edge),
|
|
|
|
.eoemb(device_eoemb)
|
2017-05-17 17:28:50 +00:00
|
|
|
);
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
generate
|
|
|
|
if (ASYNC_CLK) begin : dual_lmfc_mode
|
|
|
|
|
|
|
|
reg link_lmfc_reset = 1'b1;
|
|
|
|
reg device_lmfc_edge_d1 = 1'b0;
|
|
|
|
reg device_tx_ready = 1'b0;
|
|
|
|
|
|
|
|
jesd204_lmfc #(
|
|
|
|
.LINK_MODE(LINK_MODE),
|
|
|
|
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
|
|
|
) i_link_lmfc (
|
|
|
|
.clk(clk),
|
|
|
|
.reset(link_lmfc_reset),
|
|
|
|
|
|
|
|
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
|
|
|
.cfg_lmfc_offset('h0),
|
|
|
|
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
|
|
|
.cfg_sysref_oneshot(1'b0),
|
|
|
|
.cfg_sysref_disable(1'b1),
|
|
|
|
|
|
|
|
.sysref(sysref),
|
|
|
|
|
|
|
|
.sysref_edge(),
|
|
|
|
.sysref_alignment_error(),
|
|
|
|
|
|
|
|
.lmfc_edge(link_lmfc_edge),
|
|
|
|
.lmfc_clk(link_lmfc_clk),
|
|
|
|
.lmfc_counter(),
|
|
|
|
.lmc_edge(lmc_edge),
|
|
|
|
.lmc_quarter_edge(lmc_quarter_edge),
|
|
|
|
.eoemb(eoemb)
|
|
|
|
);
|
|
|
|
|
|
|
|
sync_bits #(
|
|
|
|
.NUM_OF_BITS (1),
|
|
|
|
.ASYNC_CLK(ASYNC_CLK)
|
|
|
|
) i_link_reset_done_cdc (
|
|
|
|
.in_bits(~reset),
|
|
|
|
.out_clk(device_clk),
|
|
|
|
.out_resetn(~device_reset),
|
|
|
|
.out_bits(link_reset_n)
|
|
|
|
);
|
|
|
|
|
|
|
|
sync_event #(
|
|
|
|
.NUM_OF_EVENTS (1)
|
|
|
|
) i_sync_lmfc (
|
|
|
|
.in_clk(device_clk),
|
|
|
|
.in_event(device_lmfc_edge & link_reset_n),
|
|
|
|
.out_clk(clk),
|
|
|
|
.out_event(lmfc_edge_synced)
|
|
|
|
);
|
|
|
|
|
|
|
|
always @(posedge clk) begin
|
|
|
|
if (reset) begin
|
|
|
|
link_lmfc_reset <= 1'b1;
|
|
|
|
end else if (lmfc_edge_synced) begin
|
|
|
|
link_lmfc_reset <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
jesd204_tx_gearbox #(
|
|
|
|
.IN_DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH),
|
|
|
|
.OUT_DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
|
|
|
.NUM_LANES(NUM_LANES),
|
|
|
|
.DEPTH(8)
|
|
|
|
) i_tx_gearbox(
|
|
|
|
.link_clk(clk),
|
|
|
|
.reset(reset),
|
|
|
|
.device_clk(device_clk),
|
|
|
|
.device_reset(device_reset),
|
|
|
|
.device_data(tx_data),
|
|
|
|
.device_lmfc_edge(device_lmfc_edge_d1),
|
|
|
|
.link_data(gearbox_data),
|
|
|
|
.output_ready(tx_ready_nx)
|
|
|
|
);
|
|
|
|
|
|
|
|
always @(posedge device_clk) begin
|
|
|
|
device_lmfc_edge_d1 <= device_lmfc_edge;
|
|
|
|
end
|
|
|
|
|
|
|
|
sync_bits #(
|
|
|
|
.NUM_OF_BITS (1),
|
|
|
|
.ASYNC_CLK(ASYNC_CLK)
|
|
|
|
) i_next_mf_ready_cdc (
|
|
|
|
.in_bits(tx_next_mf_ready),
|
|
|
|
.out_clk(device_clk),
|
|
|
|
.out_resetn(1'b1),
|
|
|
|
.out_bits(device_tx_next_mf_ready)
|
|
|
|
);
|
|
|
|
|
|
|
|
always @(posedge device_clk) begin
|
|
|
|
if (device_reset) begin
|
|
|
|
device_tx_ready <= 1'b0;
|
|
|
|
end else if (device_lmfc_edge & device_tx_next_mf_ready) begin
|
|
|
|
device_tx_ready <= 1'b1;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
jesd204_frame_mark #(
|
|
|
|
.DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH)
|
|
|
|
) i_device_frame_mark (
|
|
|
|
.clk(device_clk),
|
|
|
|
.reset(~device_tx_ready),
|
|
|
|
.cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
|
|
|
.cfg_beats_per_multiframe(device_cfg_beats_per_multiframe_s),
|
|
|
|
.cfg_octets_per_frame(device_cfg_octets_per_frame),
|
|
|
|
.sof(tx_sof),
|
|
|
|
.eof(tx_eof),
|
|
|
|
.somf(tx_somf),
|
|
|
|
.eomf(tx_eomf)
|
|
|
|
);
|
|
|
|
|
|
|
|
assign tx_ready = device_tx_ready;
|
|
|
|
|
|
|
|
end else begin
|
|
|
|
assign link_lmfc_edge = device_lmfc_edge;
|
|
|
|
assign link_lmfc_clk = device_lmfc_clk;
|
|
|
|
assign lmc_edge = device_lmc_edge;
|
|
|
|
assign lmc_quarter_edge = device_lmc_quarter_edge;
|
|
|
|
assign eoemb = device_eoemb;
|
|
|
|
assign gearbox_data = tx_data;
|
|
|
|
|
|
|
|
assign tx_sof = (LINK_MODE == 1) ? tx_sof_fm_d2 : tx_sof_fm;
|
|
|
|
assign tx_eof = (LINK_MODE == 1) ? tx_eof_fm_d2 : tx_eof_fm;
|
|
|
|
assign tx_somf = (LINK_MODE == 1) ? tx_somf_fm_d2 : tx_somf_fm;
|
|
|
|
assign tx_eomf = (LINK_MODE == 1) ? tx_eomf_fm_d2 : tx_eomf_fm;
|
|
|
|
assign tx_ready = link_tx_ready;
|
|
|
|
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
|
|
|
assign lmfc_edge = device_lmfc_edge;
|
|
|
|
assign lmfc_clk = device_lmfc_clk;
|
|
|
|
|
2020-09-28 14:29:47 +00:00
|
|
|
assign frame_mark_reset = (LINK_MODE == 1) ? eof_gen_reset : ~tx_ready_64b_next;
|
2020-01-30 22:05:13 +00:00
|
|
|
|
|
|
|
jesd204_frame_mark #(
|
|
|
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
|
|
|
) i_frame_mark (
|
|
|
|
.clk (clk),
|
|
|
|
.reset (frame_mark_reset),
|
|
|
|
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
2020-10-27 15:40:37 +00:00
|
|
|
.cfg_beats_per_multiframe (cfg_beats_per_multiframe),
|
2020-01-30 22:05:13 +00:00
|
|
|
.cfg_octets_per_frame (cfg_octets_per_frame),
|
2020-09-28 14:29:47 +00:00
|
|
|
.sof (tx_sof_fm),
|
|
|
|
.eof (tx_eof_fm),
|
|
|
|
.somf (tx_somf_fm),
|
|
|
|
.eomf (tx_eomf_fm)
|
2020-01-30 22:05:13 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
always @(posedge clk) begin
|
2020-09-28 14:29:47 +00:00
|
|
|
tx_sof_fm_d1 <= tx_sof_fm;
|
|
|
|
tx_eof_fm_d1 <= tx_eof_fm;
|
|
|
|
tx_somf_fm_d1 <= tx_somf_fm;
|
|
|
|
tx_eomf_fm_d1 <= tx_eomf_fm;
|
|
|
|
tx_sof_fm_d2 <= tx_sof_fm_d1;
|
|
|
|
tx_eof_fm_d2 <= tx_eof_fm_d1;
|
|
|
|
tx_somf_fm_d2 <= tx_somf_fm_d1;
|
|
|
|
tx_eomf_fm_d2 <= tx_eomf_fm_d1;
|
2020-01-30 22:05:13 +00:00
|
|
|
end
|
|
|
|
|
2019-10-01 15:12:11 +00:00
|
|
|
generate
|
|
|
|
genvar i;
|
|
|
|
|
|
|
|
if (LINK_MODE[0] == 1) begin : mode_8b10b
|
|
|
|
|
2020-09-28 14:29:47 +00:00
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eof_fm_d3;
|
|
|
|
reg [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d3;
|
2019-10-01 15:12:11 +00:00
|
|
|
wire [NUM_LANES-1:0] lane_cgs_enable;
|
|
|
|
wire [DW-1:0] ilas_data;
|
2020-01-30 22:05:13 +00:00
|
|
|
wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk;
|
2019-10-01 15:12:11 +00:00
|
|
|
|
|
|
|
wire cfg_generate_eomf = 1'b1;
|
|
|
|
|
2020-01-30 22:05:13 +00:00
|
|
|
always @(posedge clk) begin
|
2020-09-28 14:29:47 +00:00
|
|
|
tx_eof_fm_d3 <= tx_eof_fm_d2;
|
|
|
|
tx_eomf_fm_d3 <= tx_eomf_fm_d2;
|
2020-01-30 22:05:13 +00:00
|
|
|
end
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
jesd204_tx_ctrl #(
|
|
|
|
.NUM_LANES(NUM_LANES),
|
2018-03-29 09:38:34 +00:00
|
|
|
.NUM_LINKS(NUM_LINKS),
|
2017-05-17 17:28:50 +00:00
|
|
|
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
|
|
|
) i_tx_ctrl (
|
|
|
|
.clk(clk),
|
|
|
|
.reset(reset),
|
|
|
|
|
|
|
|
.sync(sync),
|
2020-10-27 15:40:37 +00:00
|
|
|
.lmfc_edge(link_lmfc_edge),
|
2020-09-28 14:29:47 +00:00
|
|
|
.somf(tx_somf_fm_d2),
|
|
|
|
.somf_early2(tx_somf_fm),
|
|
|
|
.eomf(tx_eomf_fm_d2),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
.lane_cgs_enable(lane_cgs_enable),
|
|
|
|
.eof_reset(eof_gen_reset),
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.tx_ready(link_tx_ready),
|
|
|
|
.tx_ready_nx(tx_ready_nx),
|
|
|
|
.tx_next_mf_ready(tx_next_mf_ready),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
.ilas_data(ilas_data),
|
|
|
|
.ilas_charisk(ilas_charisk),
|
|
|
|
|
|
|
|
.ilas_config_addr(ilas_config_addr),
|
|
|
|
.ilas_config_rd(ilas_config_rd),
|
|
|
|
.ilas_config_data(ilas_config_data),
|
|
|
|
|
|
|
|
.cfg_lanes_disable(cfg_lanes_disable),
|
2018-03-29 09:38:34 +00:00
|
|
|
.cfg_links_disable(cfg_links_disable),
|
2017-05-17 17:28:50 +00:00
|
|
|
.cfg_continuous_cgs(cfg_continuous_cgs),
|
|
|
|
.cfg_continuous_ilas(cfg_continuous_ilas),
|
|
|
|
.cfg_skip_ilas(cfg_skip_ilas),
|
|
|
|
.cfg_mframes_per_ilas(cfg_mframes_per_ilas),
|
2020-01-30 22:05:13 +00:00
|
|
|
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
2017-05-17 17:28:50 +00:00
|
|
|
.ctrl_manual_sync_request(ctrl_manual_sync_request),
|
|
|
|
|
|
|
|
.status_sync(status_sync),
|
|
|
|
.status_state(status_state)
|
|
|
|
);
|
|
|
|
|
2017-07-11 16:46:28 +00:00
|
|
|
for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
localparam D_START = i * DATA_PATH_WIDTH*8;
|
|
|
|
localparam D_STOP = D_START + DATA_PATH_WIDTH*8-1;
|
|
|
|
localparam C_START = i * DATA_PATH_WIDTH;
|
|
|
|
localparam C_STOP = C_START + DATA_PATH_WIDTH-1;
|
|
|
|
|
|
|
|
jesd204_tx_lane #(
|
2020-10-09 06:25:13 +00:00
|
|
|
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
|
|
|
.ENABLE_CHAR_REPLACE(ENABLE_CHAR_REPLACE)
|
2017-05-17 17:28:50 +00:00
|
|
|
) i_lane (
|
|
|
|
.clk(clk),
|
|
|
|
|
2020-09-28 14:29:47 +00:00
|
|
|
.eof(tx_eof_fm_d3),
|
|
|
|
.eomf(tx_eomf_fm_d3),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
|
|
|
.cgs_enable(lane_cgs_enable[i]),
|
|
|
|
|
|
|
|
.ilas_data(ilas_data[D_STOP:D_START]),
|
2020-01-30 22:05:13 +00:00
|
|
|
.ilas_charisk(ilas_charisk[C_STOP:C_START]),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.tx_data(gearbox_data[D_STOP:D_START]),
|
|
|
|
.tx_ready(link_tx_ready),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2019-08-26 14:53:17 +00:00
|
|
|
.phy_data(phy_data_r[D_STOP:D_START]),
|
|
|
|
.phy_charisk(phy_charisk_r[C_STOP:C_START]),
|
2017-05-17 17:28:50 +00:00
|
|
|
|
2020-01-30 22:05:13 +00:00
|
|
|
.cfg_octets_per_frame(cfg_octets_per_frame),
|
|
|
|
.cfg_disable_char_replacement(cfg_disable_char_replacement),
|
2017-05-17 17:28:50 +00:00
|
|
|
.cfg_disable_scrambler(cfg_disable_scrambler)
|
|
|
|
);
|
|
|
|
end
|
2019-10-01 15:12:11 +00:00
|
|
|
|
|
|
|
assign phy_header_r = 'h0;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|
|
|
localparam D_START = i * DATA_PATH_WIDTH*8;
|
|
|
|
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(
|
|
|
|
.clk(clk),
|
|
|
|
.reset(reset),
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
.tx_data(gearbox_data[D_STOP:D_START]),
|
2020-01-30 22:05:13 +00:00
|
|
|
.tx_ready(tx_ready_64b),
|
2019-10-01 15:12:11 +00:00
|
|
|
|
|
|
|
.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),
|
|
|
|
|
|
|
|
.cfg_disable_scrambler(cfg_disable_scrambler),
|
|
|
|
.cfg_header_mode(2'b0),
|
|
|
|
.cfg_lane_disable(cfg_lanes_disable[i])
|
|
|
|
);
|
|
|
|
end
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
assign tx_ready_64b_next = reset ? 1'b0 : (link_lmfc_edge || tx_ready_64b);
|
2020-09-28 14:29:47 +00:00
|
|
|
|
2019-10-01 15:12:11 +00:00
|
|
|
always @(posedge clk) begin
|
|
|
|
if (reset) begin
|
2020-01-30 22:05:13 +00:00
|
|
|
tx_ready_64b <= 1'b0;
|
2020-09-28 14:29:47 +00:00
|
|
|
end else begin
|
|
|
|
tx_ready_64b <= tx_ready_64b_next;
|
2019-10-01 15:12:11 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-27 15:40:37 +00:00
|
|
|
assign tx_ready_nx = tx_ready_64b_next;
|
|
|
|
assign tx_next_mf_ready = 1'b1;
|
|
|
|
|
|
|
|
assign link_tx_ready = tx_ready_64b;
|
2019-10-01 15:12:11 +00:00
|
|
|
// Link considered in DATA phase when SYSREF received and LEMC clock started
|
|
|
|
// running
|
2020-01-30 22:05:13 +00:00
|
|
|
assign status_state = {2{tx_ready_64b}};
|
2019-10-01 15:12:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
assign phy_charisk_r = 'h0;
|
|
|
|
assign ilas_config_rd = 'h0;
|
|
|
|
assign ilas_config_addr = 'h0;
|
|
|
|
assign status_sync = 'h0;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
endgenerate
|
|
|
|
|
2019-10-01 15:12:11 +00:00
|
|
|
pipeline_stage #(
|
|
|
|
.WIDTH(CW + DW + HW),
|
|
|
|
.REGISTERED(NUM_OUTPUT_PIPELINE)
|
|
|
|
) i_output_pipeline_stage (
|
|
|
|
.clk(clk),
|
|
|
|
.in({
|
|
|
|
phy_data_r,
|
|
|
|
phy_charisk_r,
|
|
|
|
phy_header_r
|
|
|
|
}),
|
|
|
|
.out({
|
|
|
|
phy_data,
|
|
|
|
phy_charisk,
|
|
|
|
phy_header
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
2020-12-03 13:59:33 +00:00
|
|
|
// Core static parameters
|
|
|
|
assign status_synth_params0 = {NUM_LANES};
|
|
|
|
assign status_synth_params1 = {
|
|
|
|
/*31:16 */ 16'b0,
|
2021-07-21 15:08:56 +00:00
|
|
|
/*15: 8 */ 1'b0,TPL_DATA_PATH_WIDTH[6:0],
|
2020-12-03 13:59:33 +00:00
|
|
|
/* 7: 0 */ 4'b0,DPW_LOG2[3:0]};
|
|
|
|
assign status_synth_params2 = {
|
2021-02-10 15:23:29 +00:00
|
|
|
/*31:19 */ 13'b0,
|
|
|
|
/* 18 */ ENABLE_CHAR_REPLACE[0],
|
|
|
|
/*17:13 */ 5'b0,
|
2020-12-03 13:59:33 +00:00
|
|
|
/* 12 */ ASYNC_CLK[0],
|
|
|
|
/*11:10 */ 2'b0,
|
|
|
|
/* 9: 8 */ LINK_MODE[1:0],
|
|
|
|
/* 7: 0 */ NUM_LINKS[7:0]};
|
|
|
|
|
2017-05-17 17:28:50 +00:00
|
|
|
endmodule
|