jesd204: Add support for 8-byte JESD204B, frame alignment character insertion/replacement
Add support to JESD204 RX and TX core for 8-byte 8b/10b link mode, and frame alignment character replace/insert with or without scrambling. Add support for xcelium simulator to jesd204/tb Increased cores minor version.main
parent
7be66b63c1
commit
400c3927f7
|
@ -50,7 +50,7 @@ module jesd204_up_common # (
|
|||
parameter ID = 0,
|
||||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter DATA_PATH_WIDTH = 2,
|
||||
parameter DATA_PATH_WIDTH_LOG2 = 2,
|
||||
parameter MAX_OCTETS_PER_FRAME = 256,
|
||||
parameter NUM_IRQS = 1,
|
||||
parameter EXTRA_CFG_WIDTH = 1,
|
||||
|
@ -84,19 +84,17 @@ module jesd204_up_common # (
|
|||
|
||||
output reg [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output reg [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
output reg [7:0] core_cfg_beats_per_multiframe,
|
||||
output reg [9:0] core_cfg_octets_per_multiframe,
|
||||
output reg [7:0] core_cfg_octets_per_frame,
|
||||
output reg core_cfg_disable_scrambler,
|
||||
output reg core_cfg_disable_char_replacement,
|
||||
output reg [EXTRA_CFG_WIDTH-1:0] core_extra_cfg
|
||||
);
|
||||
|
||||
localparam MAX_BEATS_PER_MULTIFRAME = (MAX_OCTETS_PER_FRAME * 32) / DATA_PATH_WIDTH;
|
||||
|
||||
reg [31:0] up_scratch = 32'h00000000;
|
||||
|
||||
reg [7:0] up_cfg_octets_per_frame = 'h00;
|
||||
reg [9-DATA_PATH_WIDTH:0] up_cfg_beats_per_multiframe = 'h00;
|
||||
reg [9:0] up_cfg_octets_per_multiframe = 'h00;
|
||||
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;
|
||||
|
@ -169,7 +167,7 @@ end
|
|||
|
||||
always @(posedge core_clk) begin
|
||||
if (core_cfg_transfer_en == 1'b1) begin
|
||||
core_cfg_beats_per_multiframe <= up_cfg_beats_per_multiframe;
|
||||
core_cfg_octets_per_multiframe <= up_cfg_octets_per_multiframe;
|
||||
core_cfg_octets_per_frame <= up_cfg_octets_per_frame;
|
||||
core_cfg_lanes_disable <= up_cfg_lanes_disable;
|
||||
core_cfg_links_disable <= up_cfg_links_disable;
|
||||
|
@ -264,7 +262,7 @@ always @(*) begin
|
|||
|
||||
/* Core configuration */
|
||||
12'h004: up_rdata = NUM_LANES;
|
||||
12'h005: up_rdata = DATA_PATH_WIDTH;
|
||||
12'h005: up_rdata = DATA_PATH_WIDTH_LOG2;
|
||||
12'h006: up_rdata = {22'b0,LINK_MODE[1:0], NUM_LINKS[7:0]};
|
||||
/* 0x07-0x0f reserved for future use */
|
||||
/* 0x10-0x1f reserved for core specific HDL configuration information */
|
||||
|
@ -287,7 +285,7 @@ always @(*) begin
|
|||
/* 24-31 */ 8'h00, /* Reserved for future extensions of octets_per_frame */
|
||||
/* 16-23 */ up_cfg_octets_per_frame,
|
||||
/* 10-15 */ 6'b000000, /* Reserved for future extensions of beats_per_multiframe */
|
||||
/* 00-09 */ up_cfg_beats_per_multiframe,{DATA_PATH_WIDTH{1'b1}}
|
||||
/* 00-09 */ up_cfg_octets_per_multiframe
|
||||
};
|
||||
12'h85: up_rdata = {
|
||||
/* 02-31 */ 30'h00, /* Reserved for future additions */
|
||||
|
@ -327,7 +325,7 @@ always @(posedge up_clk) begin
|
|||
up_reset_core <= 1'b1;
|
||||
|
||||
up_cfg_octets_per_frame <= 'h00;
|
||||
up_cfg_beats_per_multiframe <= 'h00;
|
||||
up_cfg_octets_per_multiframe <= 'h00;
|
||||
up_cfg_lanes_disable <= {NUM_LANES{1'b0}};
|
||||
up_cfg_links_disable <= {NUM_LINKS{1'b0}};
|
||||
|
||||
|
@ -358,7 +356,7 @@ always @(posedge up_clk) begin
|
|||
end
|
||||
12'h084: begin
|
||||
up_cfg_octets_per_frame <= up_wdata[23:16];
|
||||
up_cfg_beats_per_multiframe <= up_wdata[9:DATA_PATH_WIDTH];
|
||||
up_cfg_octets_per_multiframe <= up_wdata[9:0];
|
||||
end
|
||||
12'h085: begin
|
||||
up_cfg_disable_char_replacement <= up_wdata[1];
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_up_sysref #(
|
||||
parameter DATA_PATH_WIDTH = 2
|
||||
parameter DATA_PATH_WIDTH_LOG2 = 2
|
||||
) (
|
||||
input up_clk,
|
||||
input up_reset,
|
||||
|
@ -128,7 +128,7 @@ always @(posedge up_clk) begin
|
|||
end
|
||||
12'h041: begin
|
||||
/* Aligned to data path width */
|
||||
up_cfg_lmfc_offset <= up_wdata[9:DATA_PATH_WIDTH];
|
||||
up_cfg_lmfc_offset <= up_wdata[9:DATA_PATH_WIDTH_LOG2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -49,7 +49,8 @@ module axi_jesd204_rx #(
|
|||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter ENABLE_LINK_STATS = 0
|
||||
parameter ENABLE_LINK_STATS = 0,
|
||||
parameter DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4
|
||||
) (
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
|
@ -82,7 +83,7 @@ module axi_jesd204_rx #(
|
|||
|
||||
output [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
output [7:0] core_cfg_beats_per_multiframe,
|
||||
output [9:0] core_cfg_octets_per_multiframe,
|
||||
output [7:0] core_cfg_octets_per_frame,
|
||||
output core_cfg_disable_scrambler,
|
||||
output core_cfg_disable_char_replacement,
|
||||
|
@ -95,7 +96,7 @@ module axi_jesd204_rx #(
|
|||
|
||||
input [NUM_LANES-1:0] core_ilas_config_valid,
|
||||
input [2*NUM_LANES-1:0] core_ilas_config_addr,
|
||||
input [32*NUM_LANES-1:0] core_ilas_config_data,
|
||||
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] core_ilas_config_data,
|
||||
|
||||
input core_event_sysref_alignment_error,
|
||||
input core_event_sysref_edge,
|
||||
|
@ -115,10 +116,10 @@ module axi_jesd204_rx #(
|
|||
input [8*NUM_LANES-1:0] core_status_lane_frame_align_err_cnt
|
||||
);
|
||||
|
||||
localparam PCORE_VERSION = 32'h00010461; // 1.04.a
|
||||
localparam PCORE_VERSION = 32'h00010561; // 1.05.a
|
||||
localparam PCORE_MAGIC = 32'h32303452; // 204R
|
||||
|
||||
localparam DATA_PATH_WIDTH = LINK_MODE == 2 ? 3 : 2;
|
||||
localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2;
|
||||
|
||||
/* Register interface signals */
|
||||
reg [31:0] up_rdata = 'h0;
|
||||
|
@ -203,7 +204,7 @@ jesd204_up_common #(
|
|||
.ID(ID),
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2),
|
||||
.NUM_IRQS(5),
|
||||
.EXTRA_CFG_WIDTH(27),
|
||||
.LINK_MODE(LINK_MODE),
|
||||
|
@ -230,7 +231,7 @@ jesd204_up_common #(
|
|||
.up_irq_trigger(up_irq_trigger),
|
||||
.irq(irq),
|
||||
|
||||
.core_cfg_beats_per_multiframe(core_cfg_beats_per_multiframe),
|
||||
.core_cfg_octets_per_multiframe(core_cfg_octets_per_multiframe),
|
||||
.core_cfg_octets_per_frame(core_cfg_octets_per_frame),
|
||||
.core_cfg_lanes_disable(core_cfg_lanes_disable),
|
||||
.core_cfg_links_disable(core_cfg_links_disable),
|
||||
|
@ -256,7 +257,7 @@ jesd204_up_common #(
|
|||
);
|
||||
|
||||
jesd204_up_sysref #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2)
|
||||
) i_up_sysref (
|
||||
.up_clk(s_axi_aclk),
|
||||
.up_reset(up_reset),
|
||||
|
@ -280,7 +281,8 @@ jesd204_up_sysref #(
|
|||
|
||||
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),
|
||||
|
|
|
@ -122,8 +122,8 @@ set_false_path \
|
|||
|
||||
# Use -quiet here since the ILAS mem is missing in non 8b10b configuration
|
||||
set_max_delay -quiet -datapath_only \
|
||||
-from [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/mem_reg_*/*/CLK}] \
|
||||
-to [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/up_rdata_reg[*]/D}] \
|
||||
-from [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/mem_reg*/*/CLK}] \
|
||||
-to [get_pins {i_up_rx/gen_lane[*].i_up_rx_lane/i_ilas_mem/dp_*_gen.up_rdata_reg*/D}] \
|
||||
[get_property -min PERIOD $axi_clk]
|
||||
|
||||
set_false_path \
|
||||
|
|
|
@ -122,7 +122,7 @@ add_interface config conduit end
|
|||
set_interface_property config associatedClock core_clock
|
||||
set_interface_property config associatedReset core_reset
|
||||
|
||||
add_interface_port config core_cfg_beats_per_multiframe beats_per_multiframe Output 8
|
||||
add_interface_port config core_cfg_octets_per_multiframe octets_per_multiframe Output 10
|
||||
add_interface_port config core_cfg_buffer_delay buffer_delay Output 8
|
||||
add_interface_port config core_cfg_buffer_early_release buffer_early_release Output 1
|
||||
add_interface_port config core_cfg_disable_char_replacement disable_char_replacement Output 1
|
||||
|
|
|
@ -77,7 +77,7 @@ adi_add_bus "rx_cfg" "master" \
|
|||
{ \
|
||||
{ "core_cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "core_cfg_links_disable" "links_disable" } \
|
||||
{ "core_cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "core_cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "core_cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "core_cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "core_cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_up_ilas_mem (
|
||||
module jesd204_up_ilas_mem #(
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
)(
|
||||
input up_clk,
|
||||
|
||||
input up_rreq,
|
||||
|
@ -56,12 +58,14 @@ module jesd204_up_ilas_mem (
|
|||
|
||||
input core_ilas_config_valid,
|
||||
input [1:0] core_ilas_config_addr,
|
||||
input [31:0] core_ilas_config_data,
|
||||
input [DATA_PATH_WIDTH*8-1:0] core_ilas_config_data,
|
||||
|
||||
output up_ilas_ready
|
||||
);
|
||||
|
||||
reg [31:0] mem[0:3];
|
||||
localparam ILAS_DATA_LENGTH = (DATA_PATH_WIDTH == 4) ? 4 : 2;
|
||||
|
||||
reg [DATA_PATH_WIDTH*8-1:0] mem[0:ILAS_DATA_LENGTH-1];
|
||||
reg core_ilas_captured = 1'b0;
|
||||
|
||||
sync_bits i_cdc_ilas_ready (
|
||||
|
@ -75,17 +79,27 @@ always @(posedge core_clk) begin
|
|||
if (core_reset == 1'b1) begin
|
||||
core_ilas_captured <= 1'b0;
|
||||
end else begin
|
||||
if (core_ilas_config_valid == 1'b1 && core_ilas_config_addr == 'h3) begin
|
||||
if (core_ilas_config_valid == 1'b1 && core_ilas_config_addr == ILAS_DATA_LENGTH-1) begin
|
||||
core_ilas_captured <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
generate
|
||||
if(DATA_PATH_WIDTH == 4) begin : dp_4_gen
|
||||
always @(posedge up_clk) begin
|
||||
if (up_rreq == 1'b1) begin
|
||||
up_rdata <= mem[up_raddr];
|
||||
end
|
||||
end
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : dp_8_gen
|
||||
always @(posedge up_clk) begin
|
||||
if (up_rreq == 1'b1) begin
|
||||
up_rdata <= mem[up_raddr[1]] >> (up_raddr[0]*32);
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge core_clk) begin
|
||||
if (core_ilas_config_valid == 1'b1) begin
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
|
||||
module jesd204_up_rx # (
|
||||
parameter NUM_LANES = 1,
|
||||
parameter DATA_PATH_WIDTH = 2
|
||||
parameter DATA_PATH_WIDTH = 4,
|
||||
parameter DATA_PATH_WIDTH_LOG2 = 2
|
||||
) (
|
||||
input up_clk,
|
||||
input up_reset,
|
||||
|
@ -64,7 +65,7 @@ module jesd204_up_rx # (
|
|||
|
||||
input [NUM_LANES-1:0] core_ilas_config_valid,
|
||||
input [2*NUM_LANES-1:0] core_ilas_config_addr,
|
||||
input [32*NUM_LANES-1:0] core_ilas_config_data,
|
||||
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] core_ilas_config_data,
|
||||
|
||||
input [1:0] core_status_ctrl_state,
|
||||
input [2*NUM_LANES-1:0] core_status_lane_cgs_state,
|
||||
|
@ -189,7 +190,7 @@ always @(posedge up_clk) begin
|
|||
/* JESD RX configuraton */
|
||||
12'h090: begin
|
||||
up_cfg_buffer_early_release <= up_wdata[16];
|
||||
up_cfg_buffer_delay <= up_wdata[9:DATA_PATH_WIDTH];
|
||||
up_cfg_buffer_delay <= up_wdata[9:DATA_PATH_WIDTH_LOG2];
|
||||
end
|
||||
endcase
|
||||
end else if (up_wreq == 1'b1) begin
|
||||
|
@ -207,7 +208,9 @@ end
|
|||
|
||||
genvar i;
|
||||
generate for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
||||
jesd204_up_rx_lane i_up_rx_lane (
|
||||
jesd204_up_rx_lane #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_up_rx_lane (
|
||||
.up_clk(up_clk),
|
||||
.up_reset_synchronizer(up_reset_synchronizer),
|
||||
|
||||
|
@ -225,7 +228,7 @@ generate for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
|
||||
.core_ilas_config_valid(core_ilas_config_valid[i]),
|
||||
.core_ilas_config_addr(core_ilas_config_addr[2*i+1:2*i]),
|
||||
.core_ilas_config_data(core_ilas_config_data[32*i+31:32*i]),
|
||||
.core_ilas_config_data(core_ilas_config_data[(DATA_PATH_WIDTH*8*i)+(DATA_PATH_WIDTH*8)-1:DATA_PATH_WIDTH*8*i]),
|
||||
|
||||
.core_status_ifs_ready(core_status_lane_ifs_ready[i]),
|
||||
.core_status_latency(core_status_lane_latency[14*i+13:14*i])
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_up_rx_lane (
|
||||
module jesd204_up_rx_lane #(
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
)(
|
||||
input up_clk,
|
||||
input up_reset_synchronizer,
|
||||
|
||||
|
@ -62,7 +64,7 @@ module jesd204_up_rx_lane (
|
|||
|
||||
input core_ilas_config_valid,
|
||||
input [1:0] core_ilas_config_addr,
|
||||
input [31:0] core_ilas_config_data,
|
||||
input [DATA_PATH_WIDTH*8-1:0] core_ilas_config_data,
|
||||
|
||||
input core_status_ifs_ready,
|
||||
input [13:0] core_status_latency
|
||||
|
@ -133,7 +135,9 @@ always @(*) begin
|
|||
end
|
||||
end
|
||||
|
||||
jesd204_up_ilas_mem i_ilas_mem (
|
||||
jesd204_up_ilas_mem #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_ilas_mem (
|
||||
.up_clk(up_clk),
|
||||
|
||||
.up_rreq(up_rreq),
|
||||
|
|
|
@ -49,7 +49,8 @@ module axi_jesd204_tx #(
|
|||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter ENABLE_LINK_STATS = 0
|
||||
parameter ENABLE_LINK_STATS = 0,
|
||||
parameter DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4
|
||||
) (
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
|
@ -82,7 +83,7 @@ module axi_jesd204_tx #(
|
|||
|
||||
output [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
output [7:0] core_cfg_beats_per_multiframe,
|
||||
output [9:0] core_cfg_octets_per_multiframe,
|
||||
output [7:0] core_cfg_octets_per_frame,
|
||||
output [7:0] core_cfg_lmfc_offset,
|
||||
output core_cfg_sysref_oneshot,
|
||||
|
@ -96,7 +97,7 @@ module axi_jesd204_tx #(
|
|||
|
||||
input core_ilas_config_rd,
|
||||
input [1:0] core_ilas_config_addr,
|
||||
output [32*NUM_LANES-1:0] core_ilas_config_data,
|
||||
output [DATA_PATH_WIDTH*8*NUM_LANES-1:0] core_ilas_config_data,
|
||||
|
||||
input core_event_sysref_alignment_error,
|
||||
input core_event_sysref_edge,
|
||||
|
@ -107,10 +108,10 @@ module axi_jesd204_tx #(
|
|||
input [NUM_LINKS-1:0] core_status_sync
|
||||
);
|
||||
|
||||
localparam PCORE_VERSION = 32'h00010361; // 1.03.a
|
||||
localparam PCORE_VERSION = 32'h00010461; // 1.04.a
|
||||
localparam PCORE_MAGIC = 32'h32303454; // 204T
|
||||
|
||||
localparam DATA_PATH_WIDTH = LINK_MODE == 2 ? 3 : 2;
|
||||
localparam DATA_PATH_WIDTH_LOG2 = (DATA_PATH_WIDTH == 8) ? 3 : 2;
|
||||
|
||||
wire up_reset;
|
||||
|
||||
|
@ -178,7 +179,7 @@ jesd204_up_common #(
|
|||
.ID(ID),
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2),
|
||||
.NUM_IRQS(5),
|
||||
.EXTRA_CFG_WIDTH(21),
|
||||
.MAX_OCTETS_PER_FRAME(8),
|
||||
|
@ -208,7 +209,7 @@ jesd204_up_common #(
|
|||
.up_irq_trigger(up_irq_trigger),
|
||||
.irq(irq),
|
||||
|
||||
.core_cfg_beats_per_multiframe(core_cfg_beats_per_multiframe),
|
||||
.core_cfg_octets_per_multiframe(core_cfg_octets_per_multiframe),
|
||||
.core_cfg_octets_per_frame(core_cfg_octets_per_frame),
|
||||
.core_cfg_lanes_disable(core_cfg_lanes_disable),
|
||||
.core_cfg_links_disable(core_cfg_links_disable),
|
||||
|
@ -236,7 +237,7 @@ jesd204_up_common #(
|
|||
);
|
||||
|
||||
jesd204_up_sysref #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2)
|
||||
) i_up_sysref (
|
||||
.up_clk(s_axi_aclk),
|
||||
.up_reset(up_reset),
|
||||
|
@ -261,7 +262,8 @@ jesd204_up_sysref #(
|
|||
|
||||
jesd204_up_tx #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS)
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_up_tx (
|
||||
.up_clk(s_axi_aclk),
|
||||
.up_reset(up_reset),
|
||||
|
|
|
@ -120,7 +120,7 @@ add_interface config conduit end
|
|||
set_interface_property config associatedClock core_clock
|
||||
set_interface_property config associatedReset core_reset
|
||||
|
||||
add_interface_port config core_cfg_beats_per_multiframe beats_per_multiframe Output 8
|
||||
add_interface_port config core_cfg_octets_per_multiframe octets_per_multiframe Output 10
|
||||
add_interface_port config core_cfg_continuous_cgs continuous_cgs Output 1
|
||||
add_interface_port config core_cfg_continuous_ilas continuous_ilas Output 1
|
||||
add_interface_port config core_cfg_disable_char_replacement disable_char_replacement Output 1
|
||||
|
|
|
@ -75,7 +75,7 @@ adi_add_bus "tx_cfg" "master" \
|
|||
{ \
|
||||
{ "core_cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "core_cfg_links_disable" "links_disable" } \
|
||||
{ "core_cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "core_cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "core_cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "core_cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "core_cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
|
||||
module jesd204_up_tx # (
|
||||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input up_clk,
|
||||
input up_reset,
|
||||
|
@ -67,7 +68,7 @@ module jesd204_up_tx # (
|
|||
input core_clk,
|
||||
input core_ilas_config_rd,
|
||||
input [1:0] core_ilas_config_addr,
|
||||
output reg [32*NUM_LANES-1:0] core_ilas_config_data,
|
||||
output reg [DATA_PATH_WIDTH*8*NUM_LANES-1:0] core_ilas_config_data,
|
||||
|
||||
output core_ctrl_manual_sync_request,
|
||||
|
||||
|
@ -294,6 +295,8 @@ always @(posedge up_clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
generate
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_dp_4
|
||||
always @(posedge core_clk) begin
|
||||
if (core_ilas_config_rd == 1'b1) begin
|
||||
for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
|
@ -301,5 +304,15 @@ always @(posedge core_clk) begin
|
|||
end
|
||||
end
|
||||
end
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : gen_dp_8
|
||||
always @(posedge core_clk) begin
|
||||
if (core_ilas_config_rd == 1'b1) begin
|
||||
for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
core_ilas_config_data[i*64+:64] <= {up_cfg_ilas_data[i][{core_ilas_config_addr[0], 1'b1}],up_cfg_ilas_data[i][{core_ilas_config_addr[0], 1'b0}]};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -50,7 +50,7 @@ source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl
|
|||
adi_if_define "jesd204_tx_cfg"
|
||||
adi_if_ports output -1 lanes_disable
|
||||
adi_if_ports output -1 links_disable
|
||||
adi_if_ports output 8 beats_per_multiframe
|
||||
adi_if_ports output 10 octets_per_multiframe
|
||||
adi_if_ports output 8 octets_per_frame
|
||||
adi_if_ports output 8 lmfc_offset
|
||||
adi_if_ports output 1 continuous_cgs
|
||||
|
@ -81,7 +81,7 @@ adi_if_ports output 1 manual_sync_request
|
|||
adi_if_define "jesd204_rx_cfg"
|
||||
adi_if_ports output -1 lanes_disable
|
||||
adi_if_ports output -1 links_disable
|
||||
adi_if_ports output 8 beats_per_multiframe
|
||||
adi_if_ports output 10 octets_per_multiframe
|
||||
adi_if_ports output 8 octets_per_frame
|
||||
adi_if_ports output 8 lmfc_offset
|
||||
adi_if_ports output 1 buffer_early_release
|
||||
|
|
|
@ -7,6 +7,8 @@ LIBRARY_NAME := jesd204_common
|
|||
|
||||
GENERIC_DEPS += jesd204_crc12.v
|
||||
GENERIC_DEPS += jesd204_eof_generator.v
|
||||
GENERIC_DEPS += jesd204_frame_align_replace.v
|
||||
GENERIC_DEPS += jesd204_frame_mark.v
|
||||
GENERIC_DEPS += jesd204_lmfc.v
|
||||
GENERIC_DEPS += jesd204_scrambler.v
|
||||
GENERIC_DEPS += jesd204_scrambler_64b.v
|
||||
|
|
|
@ -53,6 +53,8 @@ add_files -fileset [get_filesets sources_1] [list \
|
|||
"jesd204_scrambler_64b.v" \
|
||||
"jesd204_crc12.v" \
|
||||
"jesd204_eof_generator.v" \
|
||||
"jesd204_frame_mark.v" \
|
||||
"jesd204_frame_align_replace.v" \
|
||||
"pipeline_stage.v" \
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
//
|
||||
// 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.”
|
||||
//
|
||||
|
||||
// Limitations:
|
||||
// DATA_PATH_WIDTH = 4, 8
|
||||
// F=1,2,3,4,6, and multiples of DATA_PATH_WIDTH
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_frame_align_replace #(
|
||||
parameter DATA_PATH_WIDTH = 4,
|
||||
parameter IS_RX = 1'b1
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler,
|
||||
|
||||
input [DATA_PATH_WIDTH*8-1:0] data,
|
||||
input [DATA_PATH_WIDTH-1:0] eof,
|
||||
input [DATA_PATH_WIDTH-1:0] rx_char_is_a,
|
||||
input [DATA_PATH_WIDTH-1:0] rx_char_is_f,
|
||||
input [DATA_PATH_WIDTH-1:0] tx_eomf,
|
||||
|
||||
output [DATA_PATH_WIDTH*8-1:0] data_out,
|
||||
output [DATA_PATH_WIDTH-1:0] charisk_out
|
||||
);
|
||||
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
|
||||
wire single_eof = cfg_octets_per_frame >= (DATA_PATH_WIDTH-1);
|
||||
reg [DATA_PATH_WIDTH*8-1:0] data_d1;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] data_d2;
|
||||
wire [DATA_PATH_WIDTH-1:0] char_is_align;
|
||||
reg [DATA_PATH_WIDTH-1:0] char_is_align_d1;
|
||||
reg [DATA_PATH_WIDTH-1:0] char_is_align_d2;
|
||||
wire [((DATA_PATH_WIDTH*2)+4)*8-1:0] saved_data;
|
||||
wire [((DATA_PATH_WIDTH*2)+4)-1:0] saved_char_is_align;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_replaced;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_prev_eof;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_prev_prev_eof;
|
||||
reg [7:0] data_prev_eof_single;
|
||||
reg [7:0] data_prev_eof_single_int;
|
||||
reg char_is_align_prev_single;
|
||||
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_data_1;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_prev_data_1;
|
||||
wire [DATA_PATH_WIDTH-1:0] prev_char_is_align_1;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_data_2;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_prev_data_2;
|
||||
wire [DATA_PATH_WIDTH-1:0] prev_char_is_align_2;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_data_3;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_prev_data_3;
|
||||
wire [DATA_PATH_WIDTH-1:0] prev_char_is_align_3;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_data_4;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_prev_data_4;
|
||||
wire [DATA_PATH_WIDTH-1:0] prev_char_is_align_4;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_data_6;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] prev_prev_data_6;
|
||||
wire [DATA_PATH_WIDTH-1:0] prev_char_is_align_6;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] prev_data;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] prev_prev_data;
|
||||
reg [DATA_PATH_WIDTH-1:0] prev_char_is_align;
|
||||
reg [DPW_LOG2:0] jj;
|
||||
reg [DPW_LOG2:0] ll;
|
||||
|
||||
always @(posedge clk) begin
|
||||
data_d1 <= data;
|
||||
data_d2 <= data_d1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
char_is_align_d1 <= 'b0;
|
||||
char_is_align_d2 <= 'b0;
|
||||
end else begin
|
||||
char_is_align_d1 <= char_is_align;
|
||||
char_is_align_d2 <= char_is_align_d1;
|
||||
end
|
||||
end
|
||||
|
||||
// Capture single EOF in current cycle
|
||||
|
||||
always @(eof, data) begin
|
||||
data_prev_eof_single_int = 'b0;
|
||||
for(ll = 0; ll < DATA_PATH_WIDTH; ll=ll+1) begin
|
||||
data_prev_eof_single_int = data_prev_eof_single_int | (data[ll*8 +: 8] & {8{eof[ll]}});
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
data_prev_eof_single <= 'b0;
|
||||
end else begin
|
||||
if(|eof && (!IS_RX || !(|char_is_align))) begin
|
||||
data_prev_eof_single <= data_prev_eof_single_int;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
char_is_align_prev_single <= 'b0;
|
||||
end else begin
|
||||
if(|eof) begin
|
||||
char_is_align_prev_single <= |char_is_align;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign saved_data = {data, data_d1, data_d2[(DATA_PATH_WIDTH*8)-1:(DATA_PATH_WIDTH-4)*8]};
|
||||
assign saved_char_is_align = {char_is_align, char_is_align_d1, char_is_align_d2[DATA_PATH_WIDTH-1:DATA_PATH_WIDTH-4]};
|
||||
|
||||
genvar ii;
|
||||
generate
|
||||
for (ii = 0; ii < DATA_PATH_WIDTH; ii = ii + 1) begin: gen_replace_byte
|
||||
assign prev_data_1[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+3+ii)*8 +: 8];
|
||||
assign prev_data_2[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+2+ii)*8 +: 8];
|
||||
assign prev_data_3[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+1+ii)*8 +: 8];
|
||||
assign prev_prev_data_1[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+2+ii)*8 +: 8];
|
||||
assign prev_prev_data_2[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+ii)*8 +: 8];
|
||||
assign prev_prev_data_3[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH-2+ii)*8 +: 8];
|
||||
assign prev_char_is_align_1[ii] = saved_char_is_align[(DATA_PATH_WIDTH+3+ii)];
|
||||
assign prev_char_is_align_2[ii] = saved_char_is_align[(DATA_PATH_WIDTH+2+ii)];
|
||||
assign prev_char_is_align_3[ii] = saved_char_is_align[(DATA_PATH_WIDTH+1+ii)];
|
||||
|
||||
if(DATA_PATH_WIDTH == 8) begin : gen_dp_8
|
||||
assign prev_data_4[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH+ii)*8 +: 8];
|
||||
assign prev_data_6[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH-2+ii)*8 +: 8];
|
||||
assign prev_prev_data_4[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH-4+ii)*8 +: 8];
|
||||
assign prev_prev_data_6[ii*8 +:8] = saved_data[(DATA_PATH_WIDTH-8+ii)*8 +: 8];
|
||||
assign prev_char_is_align_4[ii] = saved_char_is_align[(DATA_PATH_WIDTH+ii)];
|
||||
assign prev_char_is_align_6[ii] = saved_char_is_align[(DATA_PATH_WIDTH-2+ii)];
|
||||
end else begin
|
||||
assign prev_data_4[ii*8 +:8] = 'bX;
|
||||
assign prev_data_6[ii*8 +:8] = 'bX;
|
||||
assign prev_prev_data_4[ii*8 +:8] = 'bX;
|
||||
assign prev_prev_data_6[ii*8 +:8] = 'bX;
|
||||
assign prev_char_is_align_4[ii] = 'bX;
|
||||
assign prev_char_is_align_6[ii] = 'bX;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case(cfg_octets_per_frame)
|
||||
0:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = prev_data_1[ii*8 +:8];
|
||||
prev_prev_data[ii*8 +:8] = prev_prev_data_1[ii*8 +:8];
|
||||
prev_char_is_align[ii] = prev_char_is_align_1[ii];
|
||||
end
|
||||
1:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = prev_data_2[ii*8 +:8];
|
||||
prev_prev_data[ii*8 +:8] = prev_prev_data_2[ii*8 +:8];
|
||||
prev_char_is_align[ii] = prev_char_is_align_2[ii];
|
||||
end
|
||||
2:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = prev_data_3[ii*8 +:8];
|
||||
prev_prev_data[ii*8 +:8] = prev_prev_data_3[ii*8 +:8];
|
||||
prev_char_is_align[ii] = prev_char_is_align_3[ii];
|
||||
end
|
||||
3:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = prev_data_4[ii*8 +:8];
|
||||
prev_prev_data[ii*8 +:8] = prev_prev_data_4[ii*8 +:8];
|
||||
prev_char_is_align[ii] = prev_char_is_align_4[ii];
|
||||
end
|
||||
5:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = prev_data_6[ii*8 +:8];
|
||||
prev_prev_data[ii*8 +:8] = prev_prev_data_6[ii*8 +:8];
|
||||
prev_char_is_align[ii] = prev_char_is_align_6[ii];
|
||||
end
|
||||
default:
|
||||
begin
|
||||
prev_data[ii*8 +:8] = 'bX;
|
||||
prev_prev_data[ii*8 +:8] = 'bX;
|
||||
prev_char_is_align[ii] = 1'bX;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if(IS_RX) begin : gen_rx
|
||||
// RX
|
||||
assign char_is_align[ii] = !reset && (rx_char_is_a[ii] | rx_char_is_f[ii]);
|
||||
assign data_replaced[ii*8 +: 8] = char_is_align[ii] ? data_prev_eof[ii*8 +: 8] : data[ii*8 +: 8];
|
||||
assign data_prev_eof[ii*8 +: 8] = single_eof ? data_prev_eof_single : prev_char_is_align[ii] ? data_prev_prev_eof[ii*8 +: 8] : prev_data[ii*8 +: 8];
|
||||
assign data_prev_prev_eof[ii*8 +: 8] = prev_prev_data[ii*8 +: 8];
|
||||
end else begin : gen_tx
|
||||
// TX
|
||||
assign data_prev_eof[ii*8 +: 8] = single_eof ? data_prev_eof_single : prev_data[ii*8 +: 8];
|
||||
assign char_is_align[ii] = !reset && (tx_eomf[ii] || (eof[ii] && !(single_eof ? char_is_align_prev_single : prev_char_is_align[ii]))) && (data[ii*8 +: 8] == data_prev_eof[ii*8 +: 8]);
|
||||
assign data_replaced[ii*8 +: 8] = char_is_align[ii] ? (tx_eomf[ii] ? 8'h7c : 8'hfc) : data[ii*8 +: 8];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign data_out = (cfg_disable_char_replacement || !cfg_disable_scrambler) ? data : data_replaced;
|
||||
assign charisk_out = (IS_RX || !cfg_disable_scrambler || cfg_disable_char_replacement) ? 'b0 : char_is_align;
|
||||
|
||||
endmodule
|
|
@ -43,21 +43,19 @@
|
|||
//
|
||||
|
||||
// Limitations:
|
||||
// DATA_PATH_WIDTH = 4
|
||||
// DATA_PATH_WIDTH = 4, 8
|
||||
// F*K=4, multiples of DATA_PATH_WIDTH
|
||||
// F=1,2,3,4,6, and multiples of DATA_PATH_WIDTH
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_rx_frame_mark #(
|
||||
module jesd204_frame_mark #(
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input [DATA_PATH_WIDTH-1:0] charisk28,
|
||||
input [DATA_PATH_WIDTH*8-1:0] data,
|
||||
|
||||
output reg [DATA_PATH_WIDTH-1:0] sof,
|
||||
output reg [DATA_PATH_WIDTH-1:0] eof,
|
||||
|
@ -65,7 +63,7 @@ module jesd204_rx_frame_mark #(
|
|||
output reg [DATA_PATH_WIDTH-1:0] eomf
|
||||
);
|
||||
|
||||
localparam MAX_OCTETS_PER_FRAME = 16;
|
||||
localparam MAX_OCTETS_PER_FRAME = 32;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam CW = MAX_OCTETS_PER_FRAME > 128 ? 8 :
|
||||
MAX_OCTETS_PER_FRAME > 64 ? 7 :
|
||||
|
@ -75,21 +73,33 @@ localparam CW = MAX_OCTETS_PER_FRAME > 128 ? 8 :
|
|||
MAX_OCTETS_PER_FRAME > 4 ? 3 :
|
||||
MAX_OCTETS_PER_FRAME > 2 ? 2 : 1;
|
||||
localparam BEATS_PER_FRAME_WIDTH = CW-DPW_LOG2;
|
||||
localparam BEATS_PER_MF_WIDTH = 10-DPW_LOG2;
|
||||
|
||||
wire [BEATS_PER_MF_WIDTH-1:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe[9:DPW_LOG2];
|
||||
// For DATA_PATH_WIDTH = 8, special case if F*K%8=4
|
||||
wire octets_per_mf_4_mod_8 = (DATA_PATH_WIDTH == 8) && ~cfg_octets_per_multiframe[2];
|
||||
reg [BEATS_PER_MF_WIDTH-1:0] cur_beats_per_multiframe;
|
||||
reg mf_phase;
|
||||
reg [1:0] beat_cnt_mod_3;
|
||||
reg [BEATS_PER_FRAME_WIDTH-1:0] beat_cnt_frame;
|
||||
wire cur_sof;
|
||||
wire cur_eof;
|
||||
reg [7:0] beat_cnt_mf;
|
||||
reg [BEATS_PER_MF_WIDTH-1:0] beat_cnt_mf;
|
||||
wire cur_somf;
|
||||
wire cur_eomf;
|
||||
wire [DATA_PATH_WIDTH-1:0] default_sof;
|
||||
wire [DATA_PATH_WIDTH-1:0] default_eof;
|
||||
|
||||
wire [BEATS_PER_FRAME_WIDTH-1:0] cfg_beats_per_frame = cfg_octets_per_frame[CW-1:DPW_LOG2];
|
||||
reg [DATA_PATH_WIDTH-1:0] sof_f_3[2:0];
|
||||
reg [DATA_PATH_WIDTH-1:0] eof_f_3[2:0];
|
||||
reg [DATA_PATH_WIDTH-1:0] sof_f_6[2:0];
|
||||
reg [DATA_PATH_WIDTH-1:0] eof_f_6[2:0];
|
||||
reg [DATA_PATH_WIDTH-1:0] sof_f_12[2:0];
|
||||
reg [DATA_PATH_WIDTH-1:0] eof_f_12[2:0];
|
||||
|
||||
generate
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_dp_4
|
||||
initial begin
|
||||
sof_f_3[0] = {4'b1001};
|
||||
sof_f_3[1] = {4'b0100};
|
||||
|
@ -104,8 +114,29 @@ initial begin
|
|||
eof_f_6[1] = {4'b0010};
|
||||
eof_f_6[2] = {4'b1000};
|
||||
end
|
||||
|
||||
// Beat count % 3, to support F=3,6
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : gen_dp_8
|
||||
initial begin
|
||||
sof_f_3[0] = {8'b01001001};
|
||||
sof_f_3[1] = {8'b10010010};
|
||||
sof_f_3[2] = {8'b00100100};
|
||||
eof_f_3[0] = {8'b00100100};
|
||||
eof_f_3[1] = {8'b01001001};
|
||||
eof_f_3[2] = {8'b10010010};
|
||||
sof_f_6[0] = {8'b01000001};
|
||||
sof_f_6[1] = {8'b00010000};
|
||||
sof_f_6[2] = {8'b00000100};
|
||||
eof_f_6[0] = {8'b00100000};
|
||||
eof_f_6[1] = {8'b00001000};
|
||||
eof_f_6[2] = {8'b10000010};
|
||||
sof_f_12[0] = {8'b00000001};
|
||||
sof_f_12[1] = {8'b00010000};
|
||||
sof_f_12[2] = {8'b00000000};
|
||||
eof_f_12[0] = {8'b00000000};
|
||||
eof_f_12[1] = {8'b00001000};
|
||||
eof_f_12[2] = {8'b10000000};
|
||||
end
|
||||
end
|
||||
// Beat count % 3, to support F=3, 6, 12
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
beat_cnt_mod_3 <= 2'd0;
|
||||
|
@ -134,7 +165,10 @@ end
|
|||
assign cur_sof = beat_cnt_frame == 0;
|
||||
assign cur_eof = beat_cnt_frame == cfg_beats_per_frame;
|
||||
|
||||
// cfg_octets_per_frame must be a multiple of DATA_PATH_WIDTH'
|
||||
assign default_sof = {{DATA_PATH_WIDTH-1{1'b0}}, cur_sof};
|
||||
assign default_eof = {cur_eof, {DATA_PATH_WIDTH-1{1'b0}}};
|
||||
|
||||
// cfg_octets_per_frame must be a multiple of DATA_PATH_WIDTH
|
||||
// except for the following supported special cases
|
||||
always @(*) begin
|
||||
case(cfg_octets_per_frame)
|
||||
|
@ -153,27 +187,42 @@ always @(*) begin
|
|||
sof = sof_f_3[beat_cnt_mod_3];
|
||||
eof = eof_f_3[beat_cnt_mod_3];
|
||||
end
|
||||
8'd3:
|
||||
begin
|
||||
sof = {DATA_PATH_WIDTH/4{4'b0001}};
|
||||
eof = {DATA_PATH_WIDTH/4{4'b1000}};
|
||||
end
|
||||
8'd5:
|
||||
begin
|
||||
sof = sof_f_6[beat_cnt_mod_3];
|
||||
eof = eof_f_6[beat_cnt_mod_3];
|
||||
end
|
||||
8'd11:
|
||||
begin
|
||||
sof = (DATA_PATH_WIDTH == 4) ? default_sof : sof_f_12[beat_cnt_mod_3];
|
||||
eof = (DATA_PATH_WIDTH == 4) ? default_eof : eof_f_12[beat_cnt_mod_3];
|
||||
end
|
||||
default:
|
||||
begin
|
||||
sof = {{DATA_PATH_WIDTH-1{1'b0}}, cur_sof};
|
||||
eof = {cur_eof, {DATA_PATH_WIDTH-1{1'b0}}};
|
||||
sof = default_sof;
|
||||
eof = default_eof;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Beat count per multiframe
|
||||
// Only support F*K%4=0
|
||||
// If DATA_PATH_WIDTH == 4, or if DATA_PATH_WIDTH == 8 and F*K%8=0,
|
||||
// then multiframes always start/end at the first/last octet in the data bus
|
||||
// Otherwise, start/end of multiframe have more complicated patterns
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
beat_cnt_mf <= 8'b0;
|
||||
mf_phase <= 1'b0;
|
||||
end else begin
|
||||
if(beat_cnt_mf == cfg_beats_per_multiframe) begin
|
||||
if(beat_cnt_mf == cur_beats_per_multiframe) begin
|
||||
beat_cnt_mf <= 8'b0;
|
||||
mf_phase <= ~mf_phase;
|
||||
end else begin
|
||||
beat_cnt_mf <= beat_cnt_mf + 1'b1;
|
||||
end
|
||||
|
@ -181,13 +230,46 @@ always @(posedge clk) begin
|
|||
end
|
||||
|
||||
assign cur_somf = beat_cnt_mf == 0;
|
||||
assign cur_eomf = beat_cnt_mf == cfg_beats_per_multiframe;
|
||||
assign cur_eomf = beat_cnt_mf == cur_beats_per_multiframe;
|
||||
|
||||
// Only support F*K equals a multipe of DATA_PATH_WIDTH,
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_mf_dp_4
|
||||
always @(*) begin
|
||||
cur_beats_per_multiframe = cfg_beats_per_multiframe;
|
||||
somf = {{DATA_PATH_WIDTH-1{1'b0}}, cur_somf};
|
||||
eomf = {cur_eomf, {DATA_PATH_WIDTH-1{1'b0}}};
|
||||
end
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : gen_mf_dp_8
|
||||
always @(*) begin
|
||||
// cfg_octets_per_multiframe = 4
|
||||
if(cfg_octets_per_multiframe[9:2] == 0) begin
|
||||
cur_beats_per_multiframe = 8'hXX;
|
||||
somf = 8'h11;
|
||||
eomf = 8'h88;
|
||||
end else if(~octets_per_mf_4_mod_8) begin
|
||||
cur_beats_per_multiframe = cfg_beats_per_multiframe;
|
||||
somf = {{DATA_PATH_WIDTH-1{1'b0}}, cur_somf};
|
||||
eomf = {cur_eomf, {DATA_PATH_WIDTH-1{1'b0}}};
|
||||
end else begin
|
||||
cur_beats_per_multiframe = cfg_beats_per_multiframe - mf_phase;
|
||||
if((mf_phase == 0) && (beat_cnt_mf == 0)) begin
|
||||
somf = 8'h01;
|
||||
end else if((mf_phase == 0) && (beat_cnt_mf == cur_beats_per_multiframe)) begin
|
||||
somf = 8'h10;
|
||||
end else begin
|
||||
somf = 8'b0;
|
||||
end
|
||||
|
||||
if((mf_phase == 0) && (beat_cnt_mf == cur_beats_per_multiframe)) begin
|
||||
eomf = 8'h08;
|
||||
end else if((mf_phase == 1) && (beat_cnt_mf == cur_beats_per_multiframe)) begin
|
||||
eomf = 8'h80;
|
||||
end else begin
|
||||
eomf = 8'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
@ -44,13 +44,16 @@
|
|||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_lmfc (
|
||||
module jesd204_lmfc #(
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input sysref,
|
||||
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_oneshot,
|
||||
input cfg_sysref_disable,
|
||||
|
@ -69,6 +72,12 @@ module jesd204_lmfc (
|
|||
output reg sysref_alignment_error
|
||||
);
|
||||
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam BEATS_PER_MF_WIDTH = 10-DPW_LOG2;
|
||||
|
||||
wire [BEATS_PER_MF_WIDTH-1:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe[9:DPW_LOG2];
|
||||
reg [BEATS_PER_MF_WIDTH:0] cfg_whole_beats_per_multiframe;
|
||||
|
||||
reg sysref_r = 1'b0;
|
||||
reg sysref_d1 = 1'b0;
|
||||
reg sysref_d2 = 1'b0;
|
||||
|
@ -124,8 +133,21 @@ end
|
|||
* setting, finally deassert reset.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For DATA_PATH_WIDTH == 8, F*K%8=4, set
|
||||
* cfg_beats_per_multiframe = cfg_beats_per_multiframe*2
|
||||
* LMFC will be twice the actual length
|
||||
*/
|
||||
always @(*) begin
|
||||
if (lmfc_counter == cfg_beats_per_multiframe) begin
|
||||
if((LINK_MODE == 1) && (DATA_PATH_WIDTH == 8) && ~cfg_octets_per_multiframe[2]) begin
|
||||
cfg_whole_beats_per_multiframe = cfg_beats_per_multiframe*2;
|
||||
end else begin
|
||||
cfg_whole_beats_per_multiframe = cfg_beats_per_multiframe;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
if (lmfc_counter == cfg_whole_beats_per_multiframe) begin
|
||||
lmfc_counter_next = 'h00;
|
||||
end else begin
|
||||
lmfc_counter_next = lmfc_counter + 1'b1;
|
||||
|
@ -193,7 +215,7 @@ end
|
|||
// End of Extended MultiBlock
|
||||
always @(posedge clk) begin
|
||||
if (lmfc_active == 1'b1) begin
|
||||
eoemb <= lmfc_counter[7:5] == cfg_beats_per_multiframe[7:5];
|
||||
eoemb <= lmfc_counter[7:5] == cfg_whole_beats_per_multiframe[7:5];
|
||||
end else begin
|
||||
eoemb <= 1'b0;
|
||||
end
|
||||
|
@ -203,9 +225,9 @@ always @(posedge clk) begin
|
|||
if (reset == 1'b1) begin
|
||||
lmfc_clk_p1 <= 1'b0;
|
||||
end else if (lmfc_active == 1'b1) begin
|
||||
if (lmfc_counter == cfg_beats_per_multiframe) begin
|
||||
if (lmfc_counter == cfg_whole_beats_per_multiframe) begin
|
||||
lmfc_clk_p1 <= 1'b1;
|
||||
end else if (lmfc_counter == cfg_beats_per_multiframe[7:1]) begin
|
||||
end else if (lmfc_counter == cfg_whole_beats_per_multiframe[7:1]) begin
|
||||
lmfc_clk_p1 <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,7 @@ GENERIC_DEPS += jesd204_lane_latency_monitor.v
|
|||
GENERIC_DEPS += jesd204_rx.v
|
||||
GENERIC_DEPS += jesd204_rx_cgs.v
|
||||
GENERIC_DEPS += jesd204_rx_ctrl.v
|
||||
GENERIC_DEPS += jesd204_rx_frame_align_monitor.v
|
||||
GENERIC_DEPS += jesd204_rx_frame_mark.v
|
||||
GENERIC_DEPS += jesd204_rx_frame_align.v
|
||||
GENERIC_DEPS += jesd204_rx_lane.v
|
||||
|
||||
XILINX_DEPS += error_monitor.v
|
||||
|
|
|
@ -48,35 +48,32 @@ module align_mux #(
|
|||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input [1:0] align,
|
||||
input [2:0] align,
|
||||
input [DATA_PATH_WIDTH*8-1:0] in_data,
|
||||
input [DATA_PATH_WIDTH-1:0] in_charisk,
|
||||
output reg [DATA_PATH_WIDTH*8-1:0] out_data,
|
||||
output reg [DATA_PATH_WIDTH-1:0] out_charisk
|
||||
output [DATA_PATH_WIDTH*8-1:0] out_data,
|
||||
output [DATA_PATH_WIDTH-1:0] out_charisk
|
||||
);
|
||||
|
||||
reg [DATA_PATH_WIDTH*8-1:0] in_data_d1;
|
||||
reg [DATA_PATH_WIDTH-1:0] in_charisk_d1;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
|
||||
wire [DPW_LOG2-1:0] align_int;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] in_data_d1;
|
||||
reg [DATA_PATH_WIDTH-1:0] in_charisk_d1;
|
||||
wire [(DATA_PATH_WIDTH*8*2)-1:0] data;
|
||||
wire [(DATA_PATH_WIDTH*2)-1:0] charisk;
|
||||
|
||||
always @(posedge clk) begin
|
||||
in_data_d1 <= in_data;
|
||||
in_charisk_d1 <= in_charisk;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (align)
|
||||
'h0: out_data = in_data_d1;
|
||||
'h1: out_data = {in_data[7:0],in_data_d1[31:8]};
|
||||
'h2: out_data = {in_data[15:0],in_data_d1[31:16]};
|
||||
'h3: out_data = {in_data[23:0],in_data_d1[31:24]};
|
||||
endcase
|
||||
assign data = {in_data, in_data_d1};
|
||||
assign charisk = {in_charisk, in_charisk_d1};
|
||||
|
||||
case (align)
|
||||
'h0: out_charisk = in_charisk_d1;
|
||||
'h1: out_charisk = {in_charisk[0:0],in_charisk_d1[3:1]};
|
||||
'h2: out_charisk = {in_charisk[1:0],in_charisk_d1[3:2]};
|
||||
'h3: out_charisk = {in_charisk[2:0],in_charisk_d1[3:3]};
|
||||
endcase
|
||||
end
|
||||
assign align_int = align[DPW_LOG2-1:0];
|
||||
|
||||
assign out_data = data[align_int*8 +: (DATA_PATH_WIDTH*8)];
|
||||
assign out_charisk = charisk[align_int +: DATA_PATH_WIDTH];
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -50,6 +50,7 @@ module jesd204_ilas_monitor #(
|
|||
input clk,
|
||||
input reset,
|
||||
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [DATA_PATH_WIDTH*8-1:0] data,
|
||||
input [DATA_PATH_WIDTH-1:0] charisk28,
|
||||
|
||||
|
@ -60,17 +61,19 @@ module jesd204_ilas_monitor #(
|
|||
output data_ready_n
|
||||
);
|
||||
|
||||
reg [3:0] multi_frame_counter = 'h00;
|
||||
reg [7:0] frame_counter = 'h00;
|
||||
reg [7:0] length = 'h00;
|
||||
|
||||
localparam STATE_ILAS = 1'b1;
|
||||
localparam STATE_DATA = 1'b0;
|
||||
localparam ILAS_DATA_LENGTH = (DATA_PATH_WIDTH == 4) ? 4 : 2;
|
||||
|
||||
wire octets_per_mf_4_mod_8 = (DATA_PATH_WIDTH == 8) && ~cfg_octets_per_multiframe[2];
|
||||
reg state = STATE_ILAS;
|
||||
reg next_state;
|
||||
reg prev_was_last = 1'b0;
|
||||
reg frame_length_error = 1'b0;
|
||||
wire ilas_config_start;
|
||||
reg ilas_config_valid_i;
|
||||
reg [1:0] ilas_config_addr_i;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] ilas_config_data_i;
|
||||
|
||||
assign data_ready_n = next_state;
|
||||
|
||||
|
@ -92,7 +95,7 @@ always @(posedge clk) begin
|
|||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1 || (charisk28[3] == 1'b1 && data[31:29] == 3'h3)) begin
|
||||
if (reset == 1'b1 || (charisk28[DATA_PATH_WIDTH-1] == 1'b1 && data[(DATA_PATH_WIDTH*8)-1:(DATA_PATH_WIDTH*8)-3] == 3'h3)) begin
|
||||
prev_was_last <= 1'b1;
|
||||
end else begin
|
||||
prev_was_last <= 1'b0;
|
||||
|
@ -101,61 +104,59 @@ end
|
|||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
multi_frame_counter <= 'h00;
|
||||
end else if (charisk28[0] == 1'b1 && data[7:5] == 3'h0 && state == STATE_ILAS) begin
|
||||
multi_frame_counter <= multi_frame_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
length <= 'h00;
|
||||
end else if (prev_was_last == 1'b1) begin
|
||||
if (length == 'h00) begin
|
||||
length <= frame_counter;
|
||||
ilas_config_valid_i <= 1'b0;
|
||||
end else if (state == STATE_ILAS) begin
|
||||
if (ilas_config_start) begin
|
||||
ilas_config_valid_i <= 1'b1;
|
||||
end else if (ilas_config_addr_i == (ILAS_DATA_LENGTH-1)) begin
|
||||
ilas_config_valid_i <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
frame_length_error <= 1'b0;
|
||||
if (prev_was_last == 1'b1) begin
|
||||
if (length != 'h00 && length != frame_counter) begin
|
||||
frame_length_error <= 1'b1;
|
||||
end
|
||||
if (ilas_config_valid_i == 1'b0) begin
|
||||
ilas_config_addr_i <= 1'b0;
|
||||
end else if (ilas_config_valid_i == 1'b1) begin
|
||||
ilas_config_addr_i <= ilas_config_addr_i + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (prev_was_last == 1'b1) begin
|
||||
frame_counter <= 'h00;
|
||||
end else begin
|
||||
frame_counter <= frame_counter + 1'b1;
|
||||
end
|
||||
ilas_config_data_i <= data;
|
||||
end
|
||||
|
||||
|
||||
generate
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_dp_4
|
||||
|
||||
assign ilas_config_start = charisk28[1] && (data[15:13] == 3'h4);
|
||||
|
||||
always @(*) begin
|
||||
ilas_config_valid = ilas_config_valid_i;
|
||||
ilas_config_addr = ilas_config_addr_i;
|
||||
ilas_config_data = ilas_config_data_i;
|
||||
end
|
||||
|
||||
end else begin : gen_dp_8
|
||||
|
||||
assign ilas_config_start = octets_per_mf_4_mod_8 ?
|
||||
(charisk28[5] && (data[47:45] == 3'h4)) :
|
||||
(charisk28[1] && (data[15:13] == 3'h4));
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
ilas_config_valid <= 1'b0;
|
||||
end else if (state == STATE_ILAS) begin
|
||||
if (charisk28[1] == 1'b1 && data[15:13] == 3'h4) begin
|
||||
ilas_config_valid <= 1'b1;
|
||||
end else if (ilas_config_addr == 'h3) begin
|
||||
ilas_config_valid <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
ilas_config_valid <= ilas_config_valid_i;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ilas_config_valid == 1'b0) begin
|
||||
ilas_config_addr <= 1'b0;
|
||||
end else if (ilas_config_valid == 1'b1) begin
|
||||
ilas_config_addr <= ilas_config_addr + 1'b1;
|
||||
end
|
||||
ilas_config_addr <= ilas_config_addr_i;
|
||||
ilas_config_data <= octets_per_mf_4_mod_8 ? {data[31:0], ilas_config_data_i[63:32]} : ilas_config_data_i;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
ilas_config_data <= data;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -45,27 +45,31 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_lane_latency_monitor #(
|
||||
parameter NUM_LANES = 1
|
||||
parameter NUM_LANES = 1,
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [NUM_LANES-1:0] lane_ready,
|
||||
input [NUM_LANES*2-1:0] lane_frame_align,
|
||||
input [NUM_LANES*3-1:0] lane_frame_align,
|
||||
|
||||
output [14*NUM_LANES-1:0] lane_latency,
|
||||
output [NUM_LANES-1:0] lane_latency_ready
|
||||
);
|
||||
|
||||
reg [11:0] beat_counter;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam BEAT_CNT_WIDTH = 14-DPW_LOG2;
|
||||
|
||||
reg [11:0] lane_latency_mem[0:NUM_LANES-1];
|
||||
reg [BEAT_CNT_WIDTH-1:0] beat_counter;
|
||||
|
||||
reg [BEAT_CNT_WIDTH-1:0] lane_latency_mem[0:NUM_LANES-1];
|
||||
reg [NUM_LANES-1:0] lane_captured = 'h00;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
beat_counter <= 'h0;
|
||||
end else if (beat_counter != 'hfff) begin
|
||||
end else if (beat_counter != {BEAT_CNT_WIDTH{1'b1}}) begin
|
||||
beat_counter <= beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
@ -84,7 +88,7 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
end
|
||||
end
|
||||
|
||||
assign lane_latency[i*14+13:i*14] = {lane_latency_mem[i],lane_frame_align[i*2+1:i*2]};
|
||||
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
|
||||
|
|
|
@ -84,7 +84,7 @@ module jesd204_rx #(
|
|||
|
||||
input [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
input [NUM_LINKS-1:0] cfg_links_disable,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_disable,
|
||||
|
@ -103,7 +103,7 @@ module jesd204_rx #(
|
|||
|
||||
output [NUM_LANES-1:0] ilas_config_valid,
|
||||
output [NUM_LANES*2-1:0] ilas_config_addr,
|
||||
output [NUM_LANES*32-1:0] ilas_config_data,
|
||||
output [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data,
|
||||
|
||||
output [1:0] status_ctrl_state,
|
||||
output [2*NUM_LANES-1:0] status_lane_cgs_state,
|
||||
|
@ -118,18 +118,19 @@ module jesd204_rx #(
|
|||
* necessary.
|
||||
*/
|
||||
localparam CHAR_INFO_REGISTERED = 0;
|
||||
localparam ALIGN_MUX_REGISTERED = 0;
|
||||
localparam ALIGN_MUX_REGISTERED = 1;
|
||||
localparam SCRAMBLER_REGISTERED = 0;
|
||||
|
||||
/*
|
||||
* Maximum number of octets per multiframe for ADI JESD204 DACs is 256 (Adjust
|
||||
* as necessary). Divide by data path width.
|
||||
*/
|
||||
localparam MAX_OCTETS_PER_FRAME = 16;
|
||||
localparam MAX_OCTETS_PER_FRAME = 32;
|
||||
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;
|
||||
localparam ELASTIC_BUFFER_SIZE = MAX_BEATS_PER_MULTIFRAME;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
|
||||
localparam LMFC_COUNTER_WIDTH = MAX_BEATS_PER_MULTIFRAME > 256 ? 9 :
|
||||
MAX_BEATS_PER_MULTIFRAME > 128 ? 8 :
|
||||
|
@ -145,6 +146,8 @@ localparam DW = 8*DATA_PATH_WIDTH*NUM_LANES;
|
|||
localparam CW = DATA_PATH_WIDTH*NUM_LANES;
|
||||
localparam HW = 2*NUM_LANES;
|
||||
|
||||
wire [7:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe[9:DPW_LOG2];
|
||||
|
||||
wire [NUM_LANES-1:0] cgs_reset;
|
||||
wire [NUM_LANES-1:0] cgs_ready;
|
||||
wire [NUM_LANES-1:0] ifs_reset;
|
||||
|
@ -154,7 +157,6 @@ reg buffer_release_d1 = 1'b0;
|
|||
wire [NUM_LANES-1:0] buffer_ready_n;
|
||||
wire all_buffer_ready_n;
|
||||
|
||||
reg core_reset;
|
||||
reg eof_reset = 1'b1;
|
||||
|
||||
wire [DW-1:0] phy_data_r;
|
||||
|
@ -171,7 +173,7 @@ wire rx_valid_s = buffer_release_d1;
|
|||
wire [7:0] lmfc_counter;
|
||||
wire latency_monitor_reset;
|
||||
|
||||
wire [2*NUM_LANES-1:0] frame_align;
|
||||
wire [3*NUM_LANES-1:0] frame_align;
|
||||
wire [NUM_LANES-1:0] ifs_ready;
|
||||
|
||||
wire event_data_phase;
|
||||
|
@ -243,11 +245,14 @@ pipeline_stage #(
|
|||
})
|
||||
);
|
||||
|
||||
jesd204_lmfc i_lmfc (
|
||||
jesd204_lmfc #(
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_lmfc (
|
||||
.clk(clk),
|
||||
.reset(core_reset),
|
||||
.reset(reset),
|
||||
|
||||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.cfg_lmfc_offset(cfg_lmfc_offset),
|
||||
.cfg_sysref_oneshot(cfg_sysref_oneshot),
|
||||
.cfg_sysref_disable(cfg_sysref_disable),
|
||||
|
@ -264,21 +269,17 @@ jesd204_lmfc i_lmfc (
|
|||
.sysref_alignment_error(event_sysref_alignment_error)
|
||||
);
|
||||
|
||||
jesd204_eof_generator #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.MAX_OCTETS_PER_FRAME(MAX_OCTETS_PER_FRAME)
|
||||
) i_eof_gen (
|
||||
.clk(clk),
|
||||
.reset(eof_reset),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
|
||||
.cfg_octets_per_frame(cfg_octets_per_frame),
|
||||
.cfg_generate_eomf(1'b0),
|
||||
|
||||
.sof(rx_sof),
|
||||
.eof(rx_eof),
|
||||
.eomf()
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) i_frame_mark (
|
||||
.clk (clk),
|
||||
.reset (eof_reset),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (rx_sof),
|
||||
.eof (rx_eof),
|
||||
.somf (),
|
||||
.eomf ()
|
||||
);
|
||||
|
||||
generate
|
||||
|
@ -291,10 +292,11 @@ reg unexpected_lane_state_error_d = 1'b0;
|
|||
|
||||
jesd204_rx_ctrl #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS)
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.ENABLE_FRAME_ALIGN_ERR_RESET(ENABLE_FRAME_ALIGN_ERR_RESET)
|
||||
) i_rx_ctrl (
|
||||
.clk(clk),
|
||||
.reset(core_reset),
|
||||
.reset(reset),
|
||||
|
||||
.cfg_lanes_disable(cfg_lanes_disable),
|
||||
.cfg_links_disable(cfg_links_disable),
|
||||
|
@ -303,6 +305,7 @@ jesd204_rx_ctrl #(
|
|||
.phy_en_char_align(phy_en_char_align),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.frame_align_err_thresh_met(frame_align_err_thresh_met),
|
||||
.sync(sync),
|
||||
|
||||
.latency_monitor_reset(latency_monitor_reset),
|
||||
|
@ -317,31 +320,6 @@ jesd204_rx_ctrl #(
|
|||
.event_data_phase(event_data_phase)
|
||||
);
|
||||
|
||||
// Reset core when frame alignment errors occur
|
||||
if(ENABLE_FRAME_ALIGN_CHECK && ENABLE_FRAME_ALIGN_ERR_RESET) begin : gen_frame_align_err_reset
|
||||
|
||||
reg [7:0] reset_cnt;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
reset_cnt <= 8'h00;
|
||||
end else begin
|
||||
if(|frame_align_err_thresh_met) begin
|
||||
reset_cnt <= 8'hFF;
|
||||
end else if(reset_cnt != 0) begin
|
||||
reset_cnt <= reset_cnt - 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
core_reset <= reset | (reset_cnt != 0);
|
||||
end
|
||||
|
||||
end else begin : gen_no_frame_align_err_reset
|
||||
always @(*) begin
|
||||
core_reset = reset;
|
||||
end
|
||||
end
|
||||
|
||||
assign err_statistics_reset = ctrl_err_statistics_reset ||
|
||||
event_data_phase;
|
||||
|
||||
|
@ -361,7 +339,7 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.ENABLE_FRAME_ALIGN_CHECK(ENABLE_FRAME_ALIGN_CHECK)
|
||||
) i_lane (
|
||||
.clk(clk),
|
||||
.reset(core_reset),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_charisk(phy_charisk_r[C_STOP:C_START]),
|
||||
|
@ -378,8 +356,9 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.buffer_release_n(buffer_release_n),
|
||||
.buffer_ready_n(buffer_ready_n[i]),
|
||||
|
||||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement(cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler(cfg_disable_scrambler),
|
||||
|
||||
.err_statistics_reset(err_statistics_reset),
|
||||
|
@ -392,7 +371,7 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
|
||||
.status_cgs_state(status_lane_cgs_state[2*i+1:2*i]),
|
||||
.status_ifs_ready(ifs_ready[i]),
|
||||
.status_frame_align(frame_align[2*i+1:2*i]),
|
||||
.status_frame_align(frame_align[3*i+2:3*i]),
|
||||
|
||||
.status_frame_align_err_cnt(status_lane_frame_align_err_cnt[8*i+7:8*i])
|
||||
);
|
||||
|
@ -412,6 +391,11 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
end
|
||||
end
|
||||
end
|
||||
end else begin : gen_no_frame_align_err_thresh
|
||||
always @(*) begin
|
||||
frame_align_err_thresh_met[i] <= 1'b0;
|
||||
event_frame_alignment_error_per_lane[i] <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -445,7 +429,8 @@ always @(*) begin
|
|||
end
|
||||
|
||||
jesd204_lane_latency_monitor #(
|
||||
.NUM_LANES(NUM_LANES)
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_lane_latency_monitor (
|
||||
.clk(clk),
|
||||
.reset(latency_monitor_reset),
|
||||
|
@ -456,21 +441,19 @@ jesd204_lane_latency_monitor #(
|
|||
.lane_latency(status_lane_latency)
|
||||
);
|
||||
|
||||
assign status_lane_emb_state = 'b0;
|
||||
|
||||
end
|
||||
|
||||
if (LINK_MODE[1] == 1) begin : mode_64b66b
|
||||
|
||||
wire [NUM_LANES-1:0] emb_lock;
|
||||
|
||||
always @(*) begin
|
||||
core_reset = reset;
|
||||
end
|
||||
|
||||
jesd204_rx_ctrl_64b #(
|
||||
.NUM_LANES(NUM_LANES)
|
||||
) i_jesd204_rx_ctrl_64b (
|
||||
.clk(clk),
|
||||
.reset(core_reset),
|
||||
.reset(reset),
|
||||
|
||||
.cfg_lanes_disable(cfg_lanes_disable),
|
||||
|
||||
|
@ -497,7 +480,7 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.ELASTIC_BUFFER_SIZE(ELASTIC_BUFFER_SIZE)
|
||||
) i_lane (
|
||||
.clk(clk),
|
||||
.reset(core_reset),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_header(phy_header_r[H_STOP:H_START]),
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
|
||||
module jesd204_rx_ctrl #(
|
||||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter ENABLE_FRAME_ALIGN_ERR_RESET = 0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
@ -55,15 +56,16 @@ module jesd204_rx_ctrl #(
|
|||
input [NUM_LINKS-1:0] cfg_links_disable,
|
||||
|
||||
input phy_ready,
|
||||
|
||||
output phy_en_char_align,
|
||||
|
||||
|
||||
output [NUM_LANES-1:0] cgs_reset,
|
||||
input [NUM_LANES-1:0] cgs_ready,
|
||||
|
||||
output [NUM_LANES-1:0] ifs_reset,
|
||||
|
||||
input lmfc_edge,
|
||||
input [NUM_LANES-1:0] frame_align_err_thresh_met,
|
||||
|
||||
output [NUM_LINKS-1:0] sync,
|
||||
output reg latency_monitor_reset,
|
||||
|
@ -90,6 +92,7 @@ reg [7:0] good_counter = 'h00;
|
|||
|
||||
wire [7:0] good_cnt_limit_s;
|
||||
wire good_cnt_limit_reached_s;
|
||||
wire goto_next_state_s;
|
||||
|
||||
assign cgs_reset = cgs_rst;
|
||||
assign ifs_reset = ifs_rst;
|
||||
|
@ -125,7 +128,9 @@ always @(*) begin
|
|||
STATE_RESET: state_good = 1'b1;
|
||||
STATE_WAIT_FOR_PHY: state_good = phy_ready;
|
||||
STATE_CGS: state_good = &(cgs_ready | cfg_lanes_disable);
|
||||
STATE_SYNCHRONIZED: state_good = 1'b1;
|
||||
STATE_SYNCHRONIZED: state_good = ENABLE_FRAME_ALIGN_ERR_RESET ?
|
||||
&(~frame_align_err_thresh_met | cfg_lanes_disable) :
|
||||
1'b1;
|
||||
default: state_good = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
@ -133,6 +138,8 @@ end
|
|||
assign good_cnt_limit_s = (state == STATE_CGS) ? 'hff : 'h7;
|
||||
assign good_cnt_limit_reached_s = good_counter == good_cnt_limit_s;
|
||||
|
||||
assign goto_next_state_s = good_cnt_limit_reached_s || (state == STATE_SYNCHRONIZED);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
good_counter <= 'h00;
|
||||
|
@ -167,7 +174,7 @@ always @(posedge clk) begin
|
|||
if (reset == 1'b1) begin
|
||||
state <= STATE_RESET;
|
||||
end else begin
|
||||
if (good_cnt_limit_reached_s) begin
|
||||
if (goto_next_state_s) begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,31 +44,33 @@
|
|||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_rx_frame_align_monitor #(
|
||||
module jesd204_rx_frame_align #(
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler,
|
||||
input [DATA_PATH_WIDTH-1:0] charisk28,
|
||||
input [DATA_PATH_WIDTH*8-1:0] data,
|
||||
|
||||
output [DATA_PATH_WIDTH*8-1:0] data_replaced,
|
||||
output reg [7:0] align_err_cnt
|
||||
);
|
||||
|
||||
// Reset alignment error count on good multiframe alignment,
|
||||
// or on good frame or multiframe alignment
|
||||
// If disabled, misalignments could me masked if
|
||||
// due to cfg_beats_per_multiframe mismatch or due to
|
||||
// due to cfg_octets_per_multiframe mismatch or due to
|
||||
// a slip of a multiple of cfg_octets_per_frame octets
|
||||
localparam RESET_COUNT_ON_MF_ONLY = 1'b1;
|
||||
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 :
|
||||
DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
|
||||
function automatic [DPW_LOG2*2-1:0] count_ones(input [DATA_PATH_WIDTH*2-1:0] val);
|
||||
function automatic [DPW_LOG2*2:0] count_ones(input [DATA_PATH_WIDTH*2-1:0] val);
|
||||
reg [DPW_LOG2*2-1:0] ii;
|
||||
begin
|
||||
count_ones = 0;
|
||||
|
@ -88,23 +90,21 @@ reg [DATA_PATH_WIDTH-1:0] eomf_err;
|
|||
reg [DATA_PATH_WIDTH-1:0] eomf_good;
|
||||
reg align_good;
|
||||
reg align_err;
|
||||
reg [DPW_LOG2*2-1:0] cur_align_err_cnt;
|
||||
reg [DPW_LOG2*2:0] cur_align_err_cnt;
|
||||
wire [8:0] align_err_cnt_next;
|
||||
|
||||
|
||||
jesd204_rx_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) frame_mark (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_beats_per_multiframe (cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.charisk28 (charisk28),
|
||||
.data (data),
|
||||
.sof (),
|
||||
.eof (eof),
|
||||
.somf (),
|
||||
.eomf (eomf)
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) i_frame_mark (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (),
|
||||
.eof (eof),
|
||||
.somf (),
|
||||
.eomf (eomf)
|
||||
);
|
||||
|
||||
genvar ii;
|
||||
|
@ -124,8 +124,6 @@ for (ii = 0; ii < DATA_PATH_WIDTH; ii = ii + 1) begin: gen_k_char
|
|||
end
|
||||
end
|
||||
|
||||
// TODO: support cfg_disable_scrambler
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
eomf_err[ii] <= 1'b0;
|
||||
|
@ -133,10 +131,10 @@ for (ii = 0; ii < DATA_PATH_WIDTH; ii = ii + 1) begin: gen_k_char
|
|||
eof_err[ii] <= 1'b0;
|
||||
eof_good[ii] <= 1'b0;
|
||||
end else begin
|
||||
eomf_err[ii] <= !cfg_disable_scrambler && (char_is_a[ii] && !eomf[ii]);
|
||||
eomf_good[ii] <= !cfg_disable_scrambler && (char_is_a[ii] && eomf[ii]);
|
||||
eof_err[ii] <= !cfg_disable_scrambler && (char_is_f[ii] && !eof[ii]);
|
||||
eof_good[ii] <= !cfg_disable_scrambler && (char_is_f[ii] && eof[ii]);
|
||||
eomf_err[ii] <= char_is_a[ii] && !eomf[ii];
|
||||
eomf_good[ii] <= char_is_a[ii] && eomf[ii];
|
||||
eof_err[ii] <= char_is_f[ii] && !eof[ii];
|
||||
eof_good[ii] <= char_is_f[ii] && eof[ii];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -178,4 +176,22 @@ always @(posedge clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
jesd204_frame_align_replace #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.IS_RX (1'b1)
|
||||
) i_align_replace (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement (cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler (cfg_disable_scrambler),
|
||||
.data (data),
|
||||
.eof (eof),
|
||||
.rx_char_is_a (char_is_a),
|
||||
.rx_char_is_f (char_is_f),
|
||||
.tx_eomf ({DATA_PATH_WIDTH{1'b0}}),
|
||||
.data_out (data_replaced),
|
||||
.charisk_out ()
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -62,10 +62,10 @@ ad_ip_files jesd204_rx [list \
|
|||
jesd204_rx_cgs.v \
|
||||
jesd204_rx_ctrl.v \
|
||||
jesd204_rx_lane.v \
|
||||
jesd204_rx_frame_mark.v \
|
||||
jesd204_rx_frame_align_monitor.v \
|
||||
jesd204_rx_frame_align.v \
|
||||
jesd204_rx_constr.sdc \
|
||||
../jesd204_common/jesd204_eof_generator.v \
|
||||
../jesd204_common/jesd204_frame_mark.v \
|
||||
../jesd204_common/jesd204_lmfc.v \
|
||||
../jesd204_common/jesd204_scrambler.v \
|
||||
../jesd204_common/pipeline_stage.v \
|
||||
|
@ -125,7 +125,7 @@ add_interface config conduit end
|
|||
set_interface_property config associatedClock clock
|
||||
set_interface_property config associatedReset reset
|
||||
|
||||
add_interface_port config cfg_beats_per_multiframe beats_per_multiframe Input 8
|
||||
add_interface_port config cfg_octets_per_multiframe octets_per_multiframe Input 10
|
||||
add_interface_port config cfg_buffer_delay buffer_delay Input 8
|
||||
add_interface_port config cfg_buffer_early_release buffer_early_release Input 1
|
||||
add_interface_port config cfg_disable_char_replacement disable_char_replacement Input 1
|
||||
|
|
|
@ -58,8 +58,7 @@ adi_ip_files jesd204_rx [list \
|
|||
"jesd204_ilas_monitor.v" \
|
||||
"align_mux.v" \
|
||||
"jesd204_lane_latency_monitor.v" \
|
||||
"jesd204_rx_frame_mark.v" \
|
||||
"jesd204_rx_frame_align_monitor.v" \
|
||||
"jesd204_rx_frame_align.v" \
|
||||
"jesd204_rx_constr.ttcl" \
|
||||
"jesd204_rx.v" \
|
||||
]
|
||||
|
@ -101,7 +100,7 @@ adi_add_bus "rx_cfg" "slave" \
|
|||
{ \
|
||||
{ "cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "cfg_links_disable" "links_disable" } \
|
||||
{ "cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
@ -184,7 +183,7 @@ set_property -dict [list \
|
|||
# Data width selection
|
||||
set param [ipx::get_user_parameters DATA_PATH_WIDTH -of_objects $cc]
|
||||
set_property -dict [list \
|
||||
enablement_value false \
|
||||
enablement_tcl_expr {$LINK_MODE==1} \
|
||||
value_tcl_expr {expr $LINK_MODE*4} \
|
||||
] $param
|
||||
|
||||
|
|
|
@ -70,8 +70,9 @@ module jesd204_rx_lane #(
|
|||
output buffer_ready_n,
|
||||
input buffer_release_n,
|
||||
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler,
|
||||
|
||||
output ilas_config_valid,
|
||||
|
@ -84,11 +85,12 @@ module jesd204_rx_lane #(
|
|||
|
||||
output [1:0] status_cgs_state,
|
||||
output status_ifs_ready,
|
||||
output [1:0] status_frame_align,
|
||||
output [2:0] status_frame_align,
|
||||
output [7:0] status_frame_align_err_cnt
|
||||
);
|
||||
|
||||
localparam MAX_DATA_PATH_WIDTH = 8;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
|
||||
wire [7:0] char[0:DATA_PATH_WIDTH-1];
|
||||
wire [DATA_PATH_WIDTH-1:0] char_is_valid;
|
||||
|
@ -101,13 +103,15 @@ wire cgs_beat_is_cgs = &char_is_cgs;
|
|||
wire cgs_beat_has_error = |char_is_error;
|
||||
|
||||
reg ifs_ready = 1'b0;
|
||||
reg [1:0] frame_align = 'h00;
|
||||
reg [2:0] frame_align = 'h00;
|
||||
reg [2:0] frame_align_int;
|
||||
|
||||
wire [DATA_PATH_WIDTH*8-1:0] phy_data_s;
|
||||
wire [DATA_PATH_WIDTH-1:0] charisk28_aligned_s;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_aligned_s;
|
||||
wire [DATA_PATH_WIDTH-1:0] charisk28_aligned;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_aligned;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_replaced;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_scrambled_s;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_scrambled;
|
||||
|
||||
|
@ -117,6 +121,8 @@ reg [DATA_PATH_WIDTH-1:0] phy_char_err;
|
|||
wire ilas_monitor_reset_s;
|
||||
wire ilas_monitor_reset;
|
||||
wire buffer_ready_n_s;
|
||||
reg [DPW_LOG2:0] jj;
|
||||
reg align_found;
|
||||
|
||||
assign status_ifs_ready = ifs_ready;
|
||||
assign status_frame_align = frame_align;
|
||||
|
@ -190,17 +196,20 @@ always @(posedge clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
align_found = 1'b0;
|
||||
frame_align_int = 0;
|
||||
for(jj = 0; jj < DATA_PATH_WIDTH; jj=jj+1) begin
|
||||
if (!align_found && (char_is_cgs[jj] == 1'b0)) begin
|
||||
align_found = 1'b1;
|
||||
frame_align_int = jj;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ifs_ready == 1'b0) begin
|
||||
if (char_is_cgs[0] == 1'b0) begin
|
||||
frame_align <= 'h0;
|
||||
end else if (char_is_cgs[1] == 1'b0) begin
|
||||
frame_align <= 'h1;
|
||||
end else if (char_is_cgs[2] == 1'b0) begin
|
||||
frame_align <= 'h2;
|
||||
end else begin
|
||||
frame_align <= 'h3;
|
||||
end
|
||||
frame_align <= frame_align_int;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -213,7 +222,9 @@ pipeline_stage #(
|
|||
.out(phy_data_s)
|
||||
);
|
||||
|
||||
align_mux i_align_mux (
|
||||
align_mux #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_align_mux (
|
||||
.clk(clk),
|
||||
.align(frame_align),
|
||||
.in_data(phy_data_s),
|
||||
|
@ -242,22 +253,25 @@ pipeline_stage #(
|
|||
);
|
||||
|
||||
generate
|
||||
if(ENABLE_FRAME_ALIGN_CHECK) begin : gen_frame_align_monitor
|
||||
jesd204_rx_frame_align_monitor #(
|
||||
if(ENABLE_FRAME_ALIGN_CHECK) begin : gen_frame_align
|
||||
jesd204_rx_frame_align #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) i_align_monitor (
|
||||
.clk (clk),
|
||||
.reset (buffer_ready_n_s),
|
||||
.cfg_beats_per_multiframe (cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.cfg_disable_scrambler (cfg_disable_scrambler),
|
||||
.charisk28 (charisk28_aligned),
|
||||
.data (data_aligned),
|
||||
.align_err_cnt (status_frame_align_err_cnt)
|
||||
) i_frame_align (
|
||||
.clk (clk),
|
||||
.reset (buffer_ready_n_s),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement (cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler (cfg_disable_scrambler),
|
||||
.charisk28 (charisk28_aligned),
|
||||
.data (data_aligned),
|
||||
.data_replaced (data_replaced),
|
||||
.align_err_cnt (status_frame_align_err_cnt)
|
||||
);
|
||||
|
||||
end else begin : gen_no_frame_align_monitor
|
||||
assign status_frame_align_err_cnt = 32'd0;
|
||||
assign data_replaced = data_aligned;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
@ -268,7 +282,7 @@ jesd204_scrambler #(
|
|||
.clk(clk),
|
||||
.reset(buffer_ready_n_s),
|
||||
.enable(~cfg_disable_scrambler),
|
||||
.data_in(data_aligned),
|
||||
.data_in(data_replaced),
|
||||
.data_out(data_scrambled_s)
|
||||
);
|
||||
|
||||
|
@ -306,6 +320,7 @@ jesd204_ilas_monitor #(
|
|||
) i_ilas_monitor (
|
||||
.clk(clk),
|
||||
.reset(ilas_monitor_reset),
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.data(data_aligned),
|
||||
.charisk28(charisk28_aligned),
|
||||
|
||||
|
|
|
@ -51,13 +51,17 @@ module jesd204_rx_static_config #(
|
|||
parameter FRAMES_PER_MULTIFRAME = 32,
|
||||
parameter SCR = 1,
|
||||
parameter BUFFER_EARLY_RELEASE = 0,
|
||||
parameter LINK_MODE = 1 // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter SYSREF_DISABLE = 0,
|
||||
parameter SYSREF_ONE_SHOT = 0,
|
||||
/* Only 4, 8 are supported at the moment for 8b/10b and 8 for 64b */
|
||||
parameter DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4
|
||||
) (
|
||||
input clk,
|
||||
|
||||
output [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] cfg_links_disable,
|
||||
output [7:0] cfg_beats_per_multiframe,
|
||||
output [9:0] cfg_octets_per_multiframe,
|
||||
output [7:0] cfg_octets_per_frame,
|
||||
output [7:0] cfg_lmfc_offset,
|
||||
output cfg_sysref_oneshot,
|
||||
|
@ -70,20 +74,17 @@ module jesd204_rx_static_config #(
|
|||
output [7:0] cfg_frame_align_err_threshold
|
||||
);
|
||||
|
||||
/* Only 4 is supported at the moment for 8b/10b and 8 for 64b */
|
||||
localparam DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4;
|
||||
|
||||
assign cfg_beats_per_multiframe = (FRAMES_PER_MULTIFRAME * OCTETS_PER_FRAME / DATA_PATH_WIDTH) - 1;
|
||||
assign cfg_octets_per_multiframe = (FRAMES_PER_MULTIFRAME * OCTETS_PER_FRAME) - 1;
|
||||
assign cfg_octets_per_frame = OCTETS_PER_FRAME - 1;
|
||||
assign cfg_lmfc_offset = 3;
|
||||
assign cfg_sysref_oneshot = 1'b0;
|
||||
assign cfg_sysref_disable = 1'b0;
|
||||
assign cfg_lmfc_offset = 1;
|
||||
assign cfg_sysref_oneshot = SYSREF_ONE_SHOT;
|
||||
assign cfg_sysref_disable = SYSREF_DISABLE;
|
||||
assign cfg_buffer_delay = 'h0;
|
||||
assign cfg_buffer_early_release = BUFFER_EARLY_RELEASE;
|
||||
assign cfg_lanes_disable = {NUM_LANES{1'b0}};
|
||||
assign cfg_links_disable = {NUM_LINKS{1'b0}};
|
||||
assign cfg_disable_scrambler = SCR ? 1'b0 : 1'b1;
|
||||
assign cfg_disable_char_replacement = cfg_disable_scrambler;
|
||||
assign cfg_disable_char_replacement = 1'b0;
|
||||
assign cfg_frame_align_err_threshold = 8'd4;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -57,7 +57,7 @@ adi_add_bus "rx_cfg" "master" \
|
|||
"analog.com:interface:jesd204_rx_cfg:1.0" \
|
||||
{ \
|
||||
{ "cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
|
|
@ -67,11 +67,13 @@ module jesd204_tx #(
|
|||
|
||||
input [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data,
|
||||
output tx_ready,
|
||||
output reg [DATA_PATH_WIDTH-1:0] tx_eof,
|
||||
output reg [DATA_PATH_WIDTH-1:0] tx_sof,
|
||||
input tx_valid,
|
||||
|
||||
input [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
input [NUM_LINKS-1:0] cfg_links_disable,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_oneshot,
|
||||
|
@ -85,7 +87,7 @@ module jesd204_tx #(
|
|||
|
||||
output ilas_config_rd,
|
||||
output [1:0] ilas_config_addr,
|
||||
input [32*NUM_LANES-1:0] ilas_config_data,
|
||||
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data,
|
||||
|
||||
input ctrl_manual_sync_request,
|
||||
|
||||
|
@ -97,7 +99,7 @@ module jesd204_tx #(
|
|||
);
|
||||
|
||||
|
||||
localparam MAX_OCTETS_PER_FRAME = 8;
|
||||
localparam MAX_OCTETS_PER_FRAME = 32;
|
||||
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;
|
||||
|
@ -115,21 +117,35 @@ localparam DW = DATA_PATH_WIDTH * 8 * NUM_LANES;
|
|||
localparam CW = DATA_PATH_WIDTH * NUM_LANES;
|
||||
localparam HW = 2 * NUM_LANES;
|
||||
|
||||
|
||||
|
||||
wire [DW-1:0] phy_data_r;
|
||||
wire [CW-1:0] phy_charisk_r;
|
||||
wire [HW-1:0] phy_header_r;
|
||||
|
||||
wire eof_gen_reset;
|
||||
reg tx_ready_64b;
|
||||
wire frame_mark_reset;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_somf;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eomf;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_sof_early1;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eof_early1;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_somf_early1;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eomf_early1;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_sof_early2;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_eof_early2;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_somf_early2;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_eomf_early2;
|
||||
wire lmc_edge;
|
||||
wire lmc_quarter_edge;
|
||||
wire eoemb;
|
||||
|
||||
jesd204_lmfc i_lmfc (
|
||||
jesd204_lmfc #(
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_lmfc (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.cfg_lmfc_offset(cfg_lmfc_offset),
|
||||
.cfg_sysref_oneshot(cfg_sysref_oneshot),
|
||||
.cfg_sysref_disable(cfg_sysref_disable),
|
||||
|
@ -147,22 +163,50 @@ jesd204_lmfc i_lmfc (
|
|||
.eoemb(eoemb)
|
||||
);
|
||||
|
||||
assign frame_mark_reset = (LINK_MODE == 1) ? eof_gen_reset : ~tx_ready_64b;
|
||||
|
||||
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),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (tx_sof_early2),
|
||||
.eof (tx_eof_early2),
|
||||
.somf (tx_somf_early2),
|
||||
.eomf (tx_eomf_early2)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
tx_sof_early1 <= tx_sof_early2;
|
||||
tx_eof_early1 <= tx_eof_early2;
|
||||
tx_somf_early1 <= tx_somf_early2;
|
||||
tx_eomf_early1 <= tx_eomf_early2;
|
||||
tx_sof <= tx_sof_early1;
|
||||
tx_eof <= tx_eof_early1;
|
||||
tx_somf <= tx_somf_early1;
|
||||
tx_eomf <= tx_eomf_early1;
|
||||
end
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
|
||||
if (LINK_MODE[0] == 1) begin : mode_8b10b
|
||||
|
||||
wire eof_gen_reset;
|
||||
wire [DATA_PATH_WIDTH-1:0] eof;
|
||||
wire eomf;
|
||||
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eof_d;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eomf_d;
|
||||
wire [NUM_LANES-1:0] lane_cgs_enable;
|
||||
|
||||
wire [DW-1:0] ilas_data;
|
||||
wire [DATA_PATH_WIDTH-1:0] ilas_charisk;
|
||||
wire [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk;
|
||||
|
||||
wire cfg_generate_eomf = 1'b1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
tx_eof_d <= tx_eof;
|
||||
tx_eomf_d <= tx_eomf;
|
||||
end
|
||||
|
||||
jesd204_tx_ctrl #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
|
@ -173,6 +217,9 @@ jesd204_tx_ctrl #(
|
|||
|
||||
.sync(sync),
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.somf(tx_somf),
|
||||
.somf_early2(tx_somf_early2),
|
||||
.eomf(tx_eomf),
|
||||
|
||||
.lane_cgs_enable(lane_cgs_enable),
|
||||
.eof_reset(eof_gen_reset),
|
||||
|
@ -192,32 +239,13 @@ jesd204_tx_ctrl #(
|
|||
.cfg_continuous_ilas(cfg_continuous_ilas),
|
||||
.cfg_skip_ilas(cfg_skip_ilas),
|
||||
.cfg_mframes_per_ilas(cfg_mframes_per_ilas),
|
||||
.cfg_disable_char_replacement(cfg_disable_char_replacement),
|
||||
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.ctrl_manual_sync_request(ctrl_manual_sync_request),
|
||||
|
||||
.status_sync(status_sync),
|
||||
.status_state(status_state)
|
||||
);
|
||||
|
||||
jesd204_eof_generator #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.MAX_OCTETS_PER_FRAME(MAX_OCTETS_PER_FRAME)
|
||||
) i_eof_gen (
|
||||
.clk(clk),
|
||||
.reset(eof_gen_reset),
|
||||
|
||||
.cfg_octets_per_frame(cfg_octets_per_frame),
|
||||
.cfg_generate_eomf(cfg_generate_eomf),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.sof(),
|
||||
.eof(eof),
|
||||
.eomf(eomf)
|
||||
);
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
||||
|
||||
localparam D_START = i * DATA_PATH_WIDTH*8;
|
||||
|
@ -230,13 +258,13 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
) i_lane (
|
||||
.clk(clk),
|
||||
|
||||
.eof(eof),
|
||||
.eomf(eomf),
|
||||
.eof(tx_eof_d),
|
||||
.eomf(tx_eomf_d),
|
||||
|
||||
.cgs_enable(lane_cgs_enable[i]),
|
||||
|
||||
.ilas_data(ilas_data[D_STOP:D_START]),
|
||||
.ilas_charisk(ilas_charisk),
|
||||
.ilas_charisk(ilas_charisk[C_STOP:C_START]),
|
||||
|
||||
.tx_data(tx_data[D_STOP:D_START]),
|
||||
.tx_ready(tx_ready),
|
||||
|
@ -244,6 +272,8 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_charisk(phy_charisk_r[C_STOP:C_START]),
|
||||
|
||||
.cfg_octets_per_frame(cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement(cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler(cfg_disable_scrambler)
|
||||
);
|
||||
end
|
||||
|
@ -253,7 +283,6 @@ assign phy_header_r = 'h0;
|
|||
end
|
||||
|
||||
if (LINK_MODE[1] == 1) begin : mode_64b66b
|
||||
reg tx_ready_loc;
|
||||
|
||||
for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
||||
localparam D_START = i * DATA_PATH_WIDTH*8;
|
||||
|
@ -265,7 +294,7 @@ if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|||
.reset(reset),
|
||||
|
||||
.tx_data(tx_data[D_STOP:D_START]),
|
||||
.tx_ready(tx_ready_loc),
|
||||
.tx_ready(tx_ready_64b),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_header(phy_header_r[H_STOP:H_START]),
|
||||
|
@ -282,16 +311,16 @@ if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
tx_ready_loc <= 1'b0;
|
||||
tx_ready_64b <= 1'b0;
|
||||
end else if (lmfc_edge) begin
|
||||
tx_ready_loc <= 1'b1;
|
||||
tx_ready_64b <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign tx_ready = tx_ready_loc;
|
||||
assign tx_ready = tx_ready_64b;
|
||||
// Link considered in DATA phase when SYSREF received and LEMC clock started
|
||||
// running
|
||||
assign status_state = {2{tx_ready_loc}};
|
||||
assign status_state = {2{tx_ready_64b}};
|
||||
|
||||
|
||||
assign phy_charisk_r = 'h0;
|
||||
|
|
|
@ -54,6 +54,9 @@ module jesd204_tx_ctrl #(
|
|||
|
||||
input [NUM_LINKS-1:0] sync,
|
||||
input lmfc_edge,
|
||||
input [DATA_PATH_WIDTH-1:0] somf,
|
||||
input [DATA_PATH_WIDTH-1:0] somf_early2,
|
||||
input [DATA_PATH_WIDTH-1:0] eomf,
|
||||
|
||||
output reg [NUM_LANES-1:0] lane_cgs_enable,
|
||||
output reg eof_reset,
|
||||
|
@ -61,7 +64,7 @@ module jesd204_tx_ctrl #(
|
|||
output reg tx_ready,
|
||||
|
||||
output reg [DATA_PATH_WIDTH*8*NUM_LANES-1:0] ilas_data,
|
||||
output reg [DATA_PATH_WIDTH-1:0] ilas_charisk,
|
||||
output reg [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk,
|
||||
|
||||
output reg [1:0] ilas_config_addr,
|
||||
output reg ilas_config_rd,
|
||||
|
@ -73,28 +76,45 @@ module jesd204_tx_ctrl #(
|
|||
input cfg_continuous_ilas,
|
||||
input cfg_skip_ilas,
|
||||
input [7:0] cfg_mframes_per_ilas,
|
||||
input cfg_disable_char_replacement,
|
||||
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input ctrl_manual_sync_request,
|
||||
|
||||
output [NUM_LINKS-1:0] status_sync,
|
||||
output reg [1:0] status_state
|
||||
);
|
||||
|
||||
localparam ILAS_DATA_LENGTH = (DATA_PATH_WIDTH == 4) ? 4 : 2;
|
||||
localparam ILAS_COUNTER_WIDTH = (DATA_PATH_WIDTH == 4) ? 6 : 5;
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam BEATS_PER_MF_WIDTH = 10-DPW_LOG2;
|
||||
|
||||
// For DATA_PATH_WIDTH = 8, special case if F*K%8=4
|
||||
// Multiframe boundaries can occur in the middle of a beat
|
||||
// jesd204_lmfc will assert lmfc_edge once per two LMFC periods
|
||||
// cfg_mframes_per_ilas must be even
|
||||
wire [BEATS_PER_MF_WIDTH-1:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe[9:DPW_LOG2];
|
||||
wire octets_per_mf_4_mod_8 = (DATA_PATH_WIDTH == 8) && ~cfg_octets_per_multiframe[2];
|
||||
wire [7:0] cfg_lmfc_per_ilas = octets_per_mf_4_mod_8 ? cfg_mframes_per_ilas/2 : cfg_mframes_per_ilas;
|
||||
reg lmfc_edge_d1 = 1'b0;
|
||||
reg lmfc_edge_d2 = 1'b0;
|
||||
reg eof_reset_d;
|
||||
reg ilas_reset = 1'b1;
|
||||
reg ilas_data_reset = 1'b1;
|
||||
reg sync_request = 1'b0;
|
||||
reg sync_request_received = 1'b0;
|
||||
reg [7:0] mframe_counter = 'h00;
|
||||
reg [5:0] ilas_counter = 'h00;
|
||||
reg [ILAS_COUNTER_WIDTH-1:0] ilas_counter = 'h00;
|
||||
wire ilas_config_rd_start;
|
||||
reg ilas_config_rd_d1 = 1'b1;
|
||||
reg last_ilas_mframe = 1'b0;
|
||||
reg cgs_enable = 1'b1;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] ilas_default_data;
|
||||
|
||||
wire [NUM_LINKS-1:0] status_sync_masked;
|
||||
|
||||
genvar ii;
|
||||
genvar jj;
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (NUM_LINKS))
|
||||
i_cdc_sync (
|
||||
|
@ -140,13 +160,27 @@ end
|
|||
|
||||
always @(posedge clk) begin
|
||||
if (cfg_skip_ilas == 1'b1 ||
|
||||
mframe_counter == cfg_mframes_per_ilas) begin
|
||||
mframe_counter == cfg_lmfc_per_ilas) begin
|
||||
last_ilas_mframe <= 1'b1;
|
||||
end else begin
|
||||
last_ilas_mframe <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
if (sync_request == 1'b1 || reset == 1'b1) begin
|
||||
eof_reset = 1'b1;
|
||||
end else if (lmfc_edge == 1'b1 && sync_request_received == 1'b1) begin
|
||||
eof_reset = 1'b0;
|
||||
end else begin
|
||||
eof_reset = eof_reset_d;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
eof_reset_d <= eof_reset;
|
||||
end
|
||||
|
||||
localparam STATE_WAIT = 2'b00;
|
||||
localparam STATE_CGS = 2'b01;
|
||||
localparam STATE_ILAS = 2'b10;
|
||||
|
@ -155,7 +189,6 @@ localparam STATE_DATA = 2'b11;
|
|||
/* Timeline
|
||||
*
|
||||
* #1 lmfc_edge == 1, ilas_reset update
|
||||
* #2 eof_reset update
|
||||
* #3 {lane_,}cgs_enable, tx_ready update
|
||||
*
|
||||
* One multi-frame should at least be 3 clock cycles (TBD 64-bit data path)
|
||||
|
@ -166,7 +199,6 @@ always @(posedge clk) begin
|
|||
cgs_enable <= 1'b1;
|
||||
lane_cgs_enable <= {NUM_LANES{1'b1}};
|
||||
tx_ready <= 1'b0;
|
||||
eof_reset <= 1'b1;
|
||||
ilas_reset <= 1'b1;
|
||||
ilas_data_reset <= 1'b1;
|
||||
|
||||
|
@ -187,7 +219,6 @@ always @(posedge clk) begin
|
|||
|
||||
if (lmfc_edge_d1 == 1'b1) begin
|
||||
if (last_ilas_mframe == 1'b1 && cfg_continuous_ilas == 1'b0) begin
|
||||
eof_reset <= cfg_disable_char_replacement;
|
||||
ilas_data_reset <= 1'b1;
|
||||
end else if (cgs_enable == 1'b1) begin
|
||||
ilas_data_reset <= 1'b0;
|
||||
|
@ -215,9 +246,9 @@ end
|
|||
always @(posedge clk) begin
|
||||
if (ilas_reset == 1'b1) begin
|
||||
ilas_config_rd <= 1'b0;
|
||||
end else if (mframe_counter == 'h00 && lmfc_edge == 1'b1) begin
|
||||
end else if (ilas_config_rd_start == 1'b1) begin
|
||||
ilas_config_rd <= 1'b1;
|
||||
end else if (ilas_config_addr == 'h3) begin
|
||||
end else if (ilas_config_addr == (ILAS_DATA_LENGTH-1)) begin
|
||||
ilas_config_rd <= 1'b0;
|
||||
end
|
||||
ilas_config_rd_d1 <= ilas_config_rd;
|
||||
|
@ -239,41 +270,103 @@ always @(posedge clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
wire [31:0] ilas_default_data = {
|
||||
ilas_counter,2'h3,
|
||||
ilas_counter,2'h2,
|
||||
ilas_counter,2'h1,
|
||||
ilas_counter,2'h0
|
||||
};
|
||||
generate
|
||||
for(ii = 0; ii < DATA_PATH_WIDTH; ii=ii+1) begin : gen_default_data
|
||||
wire [(8-ILAS_COUNTER_WIDTH)-1:0] ii_sig = ii;
|
||||
assign ilas_default_data[(ii*8)+7:ii*8] = {ilas_counter, ii_sig};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_dp4
|
||||
|
||||
assign ilas_config_rd_start = mframe_counter == 'h00 && somf_early2[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ilas_data_reset == 1'b1) begin
|
||||
ilas_data <= {NUM_LANES{32'h00}};
|
||||
ilas_charisk <= 4'b0000;
|
||||
ilas_charisk <= {NUM_LANES{4'b0000}};
|
||||
end else begin
|
||||
if (ilas_config_rd_d1 == 1'b1) begin
|
||||
case (ilas_config_addr)
|
||||
2'h1: begin
|
||||
ilas_data <= (ilas_config_data & {NUM_LANES{32'hffff0000}}) |
|
||||
{NUM_LANES{16'h00,8'h9c,8'h1c}}; // /Q/ /R/
|
||||
ilas_charisk <= 4'b0011;
|
||||
ilas_charisk <= {NUM_LANES{4'b0011}};
|
||||
end
|
||||
default: begin
|
||||
ilas_data <= ilas_config_data;
|
||||
ilas_charisk <= 4'b0000;
|
||||
ilas_charisk <= {NUM_LANES{4'b0000}};
|
||||
end
|
||||
endcase
|
||||
end else if (lmfc_edge_d2 == 1'b1) begin
|
||||
ilas_data <= {NUM_LANES{ilas_default_data[31:8],8'h1c}}; // /R/
|
||||
ilas_charisk <= 4'b0001;
|
||||
ilas_charisk <= {NUM_LANES{4'b0001}};
|
||||
end else if (lmfc_edge_d1 == 1'b1) begin
|
||||
ilas_data <= {NUM_LANES{8'h7c,ilas_default_data[23:0]}}; // /A/
|
||||
ilas_charisk <= 4'b1000;
|
||||
ilas_charisk <= {NUM_LANES{4'b1000}};
|
||||
end else begin
|
||||
ilas_data <= {NUM_LANES{ilas_default_data}};
|
||||
ilas_charisk <= 4'b0000;
|
||||
ilas_charisk <= {NUM_LANES{4'b0000}};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : gen_dp8
|
||||
|
||||
reg [63:0] ilas_config_data_d[NUM_LANES-1:0];
|
||||
reg ilas_config_rd_d2 = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
ilas_config_rd_d2 <= ilas_config_rd_d1;
|
||||
end
|
||||
|
||||
for(jj = 0; jj < NUM_LANES; jj = jj + 1) begin : gen_dp8_lane
|
||||
|
||||
assign ilas_config_rd_start = (mframe_counter == 'h00) && (octets_per_mf_4_mod_8 ? somf_early2[4] : somf_early2[0]);
|
||||
|
||||
always @(posedge clk) begin
|
||||
ilas_config_data_d[jj] <= {32'b0, ilas_config_data[(jj*64)+32+:32]};
|
||||
end
|
||||
|
||||
for(ii = 0; ii < DATA_PATH_WIDTH; ii=ii+1) begin : gen_ilas_data
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ilas_data_reset) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= 8'h00;
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b0;
|
||||
end else begin
|
||||
if(somf[ii]) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= 8'h1c; // /R/
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b1;
|
||||
end else if(eomf[ii]) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= 8'h7c; // /A/
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b1;
|
||||
end else if (ilas_config_rd_d1 &&
|
||||
(ilas_config_addr == 2'h1) &&
|
||||
((octets_per_mf_4_mod_8 && (ii == 5)) ||
|
||||
(!octets_per_mf_4_mod_8 && (ii == 1)))) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= 8'h9c; // /Q/
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b1;
|
||||
end else if (octets_per_mf_4_mod_8 && ilas_config_rd_d2 && (ii < 4)) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= ilas_config_data_d[jj][ii*8+:8];
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b0;
|
||||
end else if (octets_per_mf_4_mod_8 && ilas_config_rd_d1 && (ii >= 4)) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= ilas_config_data[(jj*64)+((ii-4)*8)+:8];
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b0;
|
||||
end else if (!octets_per_mf_4_mod_8 && ilas_config_rd_d1) begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= ilas_config_data[(jj*64)+(ii*8)+:8];
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b0;
|
||||
end else begin
|
||||
ilas_data[(jj*64)+(ii*8)+:8] <= ilas_default_data[ii*8+:8];
|
||||
ilas_charisk[(jj*8)+ii] <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -59,6 +59,8 @@ ad_ip_files jesd204_tx [list \
|
|||
jesd204_tx_lane.v \
|
||||
jesd204_tx_constr.sdc \
|
||||
../jesd204_common/jesd204_eof_generator.v \
|
||||
../jesd204_common/jesd204_frame_align_replace.v \
|
||||
../jesd204_common/jesd204_frame_mark.v \
|
||||
../jesd204_common/jesd204_lmfc.v \
|
||||
../jesd204_common/jesd204_scrambler.v \
|
||||
../jesd204_common/pipeline_stage.v \
|
||||
|
@ -142,7 +144,7 @@ add_interface config conduit end
|
|||
set_interface_property config associatedClock clock
|
||||
set_interface_property config associatedReset reset
|
||||
|
||||
add_interface_port config cfg_beats_per_multiframe beats_per_multiframe Input 8
|
||||
add_interface_port config cfg_octets_per_multiframe octets_per_multiframe Input 10
|
||||
add_interface_port config cfg_continuous_cgs continuous_cgs Input 1
|
||||
add_interface_port config cfg_continuous_ilas continuous_ilas Input 1
|
||||
add_interface_port config cfg_disable_char_replacement disable_char_replacement Input 1
|
||||
|
|
|
@ -91,7 +91,7 @@ adi_add_bus "tx_cfg" "slave" \
|
|||
{ \
|
||||
{ "cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "cfg_links_disable" "links_disable" } \
|
||||
{ "cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
@ -170,7 +170,7 @@ set_property -dict [list \
|
|||
# Data width selection
|
||||
set param [ipx::get_user_parameters DATA_PATH_WIDTH -of_objects $cc]
|
||||
set_property -dict [list \
|
||||
enablement_value false \
|
||||
enablement_tcl_expr {$LINK_MODE==1} \
|
||||
value_tcl_expr {expr $LINK_MODE*4} \
|
||||
] $param
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ module jesd204_tx_lane #(
|
|||
input clk,
|
||||
|
||||
input [DATA_PATH_WIDTH-1:0] eof,
|
||||
input eomf,
|
||||
input [DATA_PATH_WIDTH-1:0] eomf,
|
||||
|
||||
input cgs_enable,
|
||||
|
||||
|
@ -63,12 +63,23 @@ module jesd204_tx_lane #(
|
|||
output reg [DATA_PATH_WIDTH*8-1:0] phy_data,
|
||||
output reg [DATA_PATH_WIDTH-1:0] phy_charisk,
|
||||
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler
|
||||
);
|
||||
|
||||
wire [DATA_PATH_WIDTH*8-1:0] scrambled_data;
|
||||
wire [7:0] scrambled_char[0:DATA_PATH_WIDTH-1];
|
||||
reg [7:0] char_align[0:DATA_PATH_WIDTH-1];
|
||||
wire [DATA_PATH_WIDTH*8-1:0] scrambled_data_d;
|
||||
wire cgs_enable_d;
|
||||
wire tx_ready_d;
|
||||
wire [DATA_PATH_WIDTH-1:0] eof_d;
|
||||
wire [DATA_PATH_WIDTH-1:0] eomf_d;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] ilas_data_d;
|
||||
wire [DATA_PATH_WIDTH-1:0] ilas_charisk_d;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_replaced;
|
||||
wire [DATA_PATH_WIDTH-1:0] charisk_replaced;
|
||||
wire [7:0] scrambled_char[0:DATA_PATH_WIDTH-1];
|
||||
reg [7:0] char_align[0:DATA_PATH_WIDTH-1];
|
||||
|
||||
jesd204_scrambler #(
|
||||
.WIDTH(DATA_PATH_WIDTH*8),
|
||||
|
@ -81,14 +92,57 @@ jesd204_scrambler #(
|
|||
.data_out(scrambled_data)
|
||||
);
|
||||
|
||||
pipeline_stage #(
|
||||
.WIDTH((DATA_PATH_WIDTH*19) + 2),
|
||||
.REGISTERED(1)
|
||||
) i_lane_pipeline_stage (
|
||||
.clk(clk),
|
||||
.in({
|
||||
cgs_enable,
|
||||
tx_ready,
|
||||
eof,
|
||||
eomf,
|
||||
scrambled_data,
|
||||
ilas_data,
|
||||
ilas_charisk
|
||||
}),
|
||||
.out({
|
||||
cgs_enable_d,
|
||||
tx_ready_d,
|
||||
eof_d,
|
||||
eomf_d,
|
||||
scrambled_data_d,
|
||||
ilas_data_d,
|
||||
ilas_charisk_d
|
||||
})
|
||||
);
|
||||
|
||||
jesd204_frame_align_replace #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.IS_RX (1'b0)
|
||||
) i_align_replace (
|
||||
.clk (clk),
|
||||
.reset (~tx_ready_d),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement (cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler (cfg_disable_scrambler),
|
||||
.data (scrambled_data_d),
|
||||
.eof (eof_d),
|
||||
.rx_char_is_a ({DATA_PATH_WIDTH{1'b0}}),
|
||||
.rx_char_is_f ({DATA_PATH_WIDTH{1'b0}}),
|
||||
.tx_eomf (eomf_d),
|
||||
.data_out (data_replaced),
|
||||
.charisk_out (charisk_replaced)
|
||||
);
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
|
||||
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: gen_char
|
||||
assign scrambled_char[i] = scrambled_data[i*8+7:i*8];
|
||||
assign scrambled_char[i] = scrambled_data_d[i*8+7:i*8];
|
||||
|
||||
always @(*) begin
|
||||
if (i == DATA_PATH_WIDTH-1 && eomf == 1'b1) begin
|
||||
if (eomf_d[i]) begin
|
||||
char_align[i] = 8'h7c; // /A/
|
||||
end else begin
|
||||
char_align[i] = 8'hfc; // /F/
|
||||
|
@ -96,12 +150,16 @@ for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: gen_char
|
|||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (cgs_enable == 1'b1) begin
|
||||
phy_charisk[i] <= 1'b1;
|
||||
end else if (eof[i] == 1'b1 && scrambled_char[i] == char_align[i]) begin
|
||||
if (cgs_enable_d) begin
|
||||
phy_charisk[i] <= 1'b1;
|
||||
end else if (tx_ready_d) begin
|
||||
if(!cfg_disable_scrambler) begin
|
||||
phy_charisk[i] <= eof_d[i] && (scrambled_char[i] == char_align[i]);
|
||||
end else begin
|
||||
phy_charisk[i] <= charisk_replaced[i];
|
||||
end
|
||||
end else begin
|
||||
phy_charisk[i] <= ilas_charisk[i];
|
||||
phy_charisk[i] <= ilas_charisk_d[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -109,10 +167,14 @@ end
|
|||
endgenerate
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (cgs_enable == 1'b1) begin
|
||||
if (cgs_enable_d) begin
|
||||
phy_data <= {DATA_PATH_WIDTH{8'hbc}};
|
||||
end else begin
|
||||
phy_data <= (tx_ready) ? scrambled_data : ilas_data;
|
||||
if(tx_ready_d) begin
|
||||
phy_data <= data_replaced;
|
||||
end else begin
|
||||
phy_data <= ilas_data_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -60,16 +60,18 @@ module jesd204_ilas_config_static #(
|
|||
parameter JESDV = 3'h1,
|
||||
parameter CF = 5'h00,
|
||||
parameter HD = 1'b1,
|
||||
parameter NUM_LANES = 1
|
||||
parameter NUM_LANES = 1,
|
||||
parameter DATA_PATH_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
|
||||
input [1:0] ilas_config_addr,
|
||||
input ilas_config_rd,
|
||||
output reg [32*NUM_LANES-1:0] ilas_config_data
|
||||
output reg [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data
|
||||
);
|
||||
|
||||
wire [31:0] ilas_mem[0:3];
|
||||
reg [31:0] ilas_lane_mem[0:NUM_LANES-1][0:3];
|
||||
|
||||
assign ilas_mem[0][15:0] = 8'h00;
|
||||
assign ilas_mem[0][23:16] = DID; // DID
|
||||
|
@ -106,17 +108,26 @@ assign ilas_mem[3][31:24] = ilas_mem[0][23:16] + ilas_mem[0][31:24] +
|
|||
|
||||
generate
|
||||
genvar i;
|
||||
genvar j;
|
||||
|
||||
for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
||||
for(j = 0; j < 4; j = j + 1) begin : gen_word
|
||||
always @(*) begin
|
||||
ilas_lane_mem[i][j] = ilas_mem[j];
|
||||
case(j)
|
||||
1: ilas_lane_mem[i][j][4:0] = i;
|
||||
3: ilas_lane_mem[i][j][31:24] = ilas_mem[3][31:24] + i;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ilas_config_rd == 1'b1) begin
|
||||
ilas_config_data[i*32+31:i*32] <= ilas_mem[ilas_config_addr];
|
||||
|
||||
/* Overwrite special cases */
|
||||
case (ilas_config_addr)
|
||||
'h1: ilas_config_data[i*32+4:i*32] <= i;
|
||||
'h3: ilas_config_data[i*32+31:i*32+24] <= ilas_mem[ilas_config_addr][31:24] + i;
|
||||
endcase
|
||||
if(DATA_PATH_WIDTH == 4) begin
|
||||
ilas_config_data[i*32+31:i*32] <= ilas_lane_mem[i][ilas_config_addr];
|
||||
end else begin
|
||||
ilas_config_data[i*64+63:i*64] <= {ilas_lane_mem[i][{ilas_config_addr[0], 1'b1}], ilas_lane_mem[i][{ilas_config_addr[0], 1'b0}]};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
26
library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v
Normal file → Executable file
26
library/jesd204/jesd204_tx_static_config/jesd204_tx_static_config.v
Normal file → Executable file
|
@ -54,13 +54,17 @@ module jesd204_tx_static_config #(
|
|||
parameter NP = 16,
|
||||
parameter HIGH_DENSITY = 1,
|
||||
parameter SCR = 1,
|
||||
parameter LINK_MODE = 1 // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter SYSREF_DISABLE = 0,
|
||||
parameter SYSREF_ONE_SHOT = 0,
|
||||
/* Only 4, 8 are supported at the moment for 8b/10b and 8 for 64b */
|
||||
parameter DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4
|
||||
) (
|
||||
input clk,
|
||||
|
||||
output [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] cfg_links_disable,
|
||||
output [7:0] cfg_beats_per_multiframe,
|
||||
output [9:0] cfg_octets_per_multiframe,
|
||||
output [7:0] cfg_octets_per_frame,
|
||||
output [7:0] cfg_lmfc_offset,
|
||||
output cfg_sysref_oneshot,
|
||||
|
@ -74,23 +78,20 @@ module jesd204_tx_static_config #(
|
|||
|
||||
input ilas_config_rd,
|
||||
input [1:0] ilas_config_addr,
|
||||
output [32*NUM_LANES-1:0] ilas_config_data
|
||||
output [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data
|
||||
);
|
||||
|
||||
/* Only 4 is supported at the moment for 8b/10b and 8 for 64b */
|
||||
localparam DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4;
|
||||
|
||||
assign cfg_beats_per_multiframe = (FRAMES_PER_MULTIFRAME * OCTETS_PER_FRAME / DATA_PATH_WIDTH) - 1;
|
||||
assign cfg_octets_per_multiframe = (FRAMES_PER_MULTIFRAME * OCTETS_PER_FRAME) - 1;
|
||||
assign cfg_octets_per_frame = OCTETS_PER_FRAME - 1;
|
||||
assign cfg_lmfc_offset = 3;
|
||||
assign cfg_sysref_oneshot = 1'b0;
|
||||
assign cfg_sysref_disable = 1'b0;
|
||||
assign cfg_lmfc_offset = 1;
|
||||
assign cfg_sysref_oneshot = SYSREF_ONE_SHOT;
|
||||
assign cfg_sysref_disable = SYSREF_DISABLE;
|
||||
assign cfg_continuous_cgs = 1'b0;
|
||||
assign cfg_continuous_ilas = 1'b0;
|
||||
assign cfg_skip_ilas = 1'b0;
|
||||
assign cfg_mframes_per_ilas = 3;
|
||||
assign cfg_disable_scrambler = SCR ? 1'b0 : 1'b1;
|
||||
assign cfg_disable_char_replacement = cfg_disable_scrambler;
|
||||
assign cfg_disable_char_replacement = 1'b0;
|
||||
assign cfg_lanes_disable = {NUM_LANES{1'b0}};
|
||||
assign cfg_links_disable = {NUM_LINKS{1'b0}};
|
||||
|
||||
|
@ -109,7 +110,8 @@ jesd204_ilas_config_static #(
|
|||
.JESDV(3'h1),
|
||||
.CF(5'h00),
|
||||
.HD(HIGH_DENSITY),
|
||||
.NUM_LANES(NUM_LANES)
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_ilas_config (
|
||||
.clk(clk),
|
||||
.ilas_config_addr(ilas_config_addr),
|
||||
|
|
|
@ -58,7 +58,7 @@ adi_add_bus "tx_cfg" "master" \
|
|||
"analog.com:interface:jesd204_tx_cfg:1.0" \
|
||||
{ \
|
||||
{ "cfg_lanes_disable" "lanes_disable" } \
|
||||
{ "cfg_beats_per_multiframe" "beats_per_multiframe" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
SOURCE="frame_align_tb.v"
|
||||
SOURCE+=" ../jesd204_common/jesd204_lmfc.v ../jesd204_common/jesd204_scrambler.v ../jesd204_common/jesd204_eof_generator.v"
|
||||
SOURCE+=" ../jesd204_common/pipeline_stage.v"
|
||||
SOURCE+=" ../jesd204_common/pipeline_stage.v ../jesd204_common/jesd204_frame_mark.v ../jesd204_common/jesd204_frame_align_replace.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx.v ../jesd204_rx/jesd204_rx_lane.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_ilas_monitor.v ../jesd204_rx/align_mux.v ../jesd204_rx/jesd204_rx_cgs.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl.v ../jesd204_rx/elastic_buffer.v ../jesd204_rx/jesd204_lane_latency_monitor.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_frame_mark.v ../jesd204_rx/jesd204_rx_frame_align_monitor.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_frame_align.v"
|
||||
SOURCE+=" ../jesd204_rx_static_config/jesd204_rx_static_config.v"
|
||||
SOURCE+=" ../jesd204_tx/jesd204_tx.v ../jesd204_tx/jesd204_tx_ctrl.v ../jesd204_tx/jesd204_tx_lane.v"
|
||||
SOURCE+=" ../jesd204_tx_static_config/jesd204_tx_static_config.v"
|
||||
|
|
|
@ -48,17 +48,27 @@ module frame_align_tb;
|
|||
parameter VCD_FILE = "frame_align_tb.vcd";
|
||||
parameter NUM_LANES = 4;
|
||||
parameter NUM_LINKS = 1;
|
||||
parameter OCTETS_PER_FRAME = 4;
|
||||
parameter FRAMES_PER_MULTIFRAME = 16;
|
||||
parameter ENABLE_SCRAMBLER = 1;
|
||||
parameter OCTETS_PER_FRAME = 3;
|
||||
parameter FRAMES_PER_MULTIFRAME = 8;
|
||||
parameter NUM_CONVERTERS = 1;
|
||||
parameter N = 16;
|
||||
parameter NP = 16;
|
||||
parameter HIGH_DENSITY = 1'b0;
|
||||
parameter ENABLE_SCRAMBLER = 0;
|
||||
parameter BUFFER_EARLY_RELEASE = 1;
|
||||
parameter SYSREF_DISABLE = 1;
|
||||
parameter SYSREF_ONE_SHOT = 0;
|
||||
parameter LANE_DELAY = 1;
|
||||
parameter DATA_PATH_WIDTH = 8;
|
||||
parameter DATA_RANDOM = ENABLE_SCRAMBLER ? 0 : 1;
|
||||
parameter ALIGN_ERROR_PERCENT = 50;
|
||||
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam BEATS_PER_MULTIFRAME = OCTETS_PER_FRAME * FRAMES_PER_MULTIFRAME / 4;
|
||||
localparam TX_LATENCY = 3;
|
||||
localparam RX_LATENCY = 3;
|
||||
localparam BASE_LATENCY = TX_LATENCY + RX_LATENCY;
|
||||
wire [31:0] RX_LATENCY = 3 + i_rx.CHAR_INFO_REGISTERED + i_rx.ALIGN_MUX_REGISTERED + i_rx.SCRAMBLER_REGISTERED;
|
||||
wire [31:0] BASE_LATENCY = TX_LATENCY + RX_LATENCY;
|
||||
localparam SYSREF_HALF_COUNT = OCTETS_PER_FRAME * FRAMES_PER_MULTIFRAME;
|
||||
|
||||
`define TIMEOUT 1000000
|
||||
|
||||
|
@ -66,10 +76,13 @@ module frame_align_tb;
|
|||
|
||||
reg [5:0] tx_counter = 'h00;
|
||||
reg [5:0] rx_counter = 'h00;
|
||||
reg [NUM_LANES*32-1:0] rx_mask = 'hffff0000;
|
||||
reg [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_mask = 64'hffffffffffff0000;
|
||||
wire tx_ready;
|
||||
wire rx_valid;
|
||||
wire [NUM_LANES*32-1:0] rx_data;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_data;
|
||||
wire [DATA_PATH_WIDTH-1:0] rx_eof;
|
||||
wire [DATA_PATH_WIDTH-1:0] rx_sof;
|
||||
wire cur_data_mismatch;
|
||||
reg data_mismatch = 1'b1;
|
||||
wire [NUM_LINKS-1:0] sync;
|
||||
|
||||
|
@ -85,45 +98,63 @@ module frame_align_tb;
|
|||
if (sync == 1'b0) begin
|
||||
rx_counter <= 'h00000000;
|
||||
if (ENABLE_SCRAMBLER == 1'b1) begin
|
||||
rx_mask <= {NUM_LANES{32'hffff0000}}; // First two octets are invalid due to scrambling
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffff0000}}; // First two octets are invalid due to scrambling
|
||||
end else begin
|
||||
rx_mask <= {NUM_LANES{32'hffffffff}};
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffffffff}};
|
||||
end
|
||||
end else if (rx_valid == 1'b1) begin
|
||||
rx_counter <= rx_counter + 1'b1;
|
||||
rx_mask <= {NUM_LANES{32'hffffffff}};
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffffffff}};
|
||||
end
|
||||
end
|
||||
|
||||
wire [31:0] tx_data = {tx_counter,2'h3,tx_counter,2'h2,tx_counter,2'h1,tx_counter,2'h0};
|
||||
wire [31:0] rx_ref_data = {rx_counter,2'h3,rx_counter,2'h2,rx_counter,2'h1,rx_counter,2'h0};
|
||||
reg [(DATA_PATH_WIDTH*8)-1:0] tx_random_data;
|
||||
wire [(DATA_PATH_WIDTH*8)-1:0] tx_data;
|
||||
wire [(DATA_PATH_WIDTH*8)-1:0] rx_ref_data;
|
||||
|
||||
wire [NUM_LANES*32-1:0] phy_data_out;
|
||||
wire [NUM_LANES*4-1:0] phy_charisk_out;
|
||||
wire [NUM_LANES*32-1:0] phy_data_delayed;
|
||||
wire [NUM_LANES*4-1:0] phy_charisk_delayed;
|
||||
reg [NUM_LANES*32-1:0] phy_data_in;
|
||||
reg [NUM_LANES*4-1:0] phy_charisk_in;
|
||||
genvar ii;
|
||||
generate
|
||||
for(ii = 0; ii < DATA_PATH_WIDTH; ii=ii+1) begin : data_gen
|
||||
wire [1:0] ii_sig = ii;
|
||||
|
||||
always @(posedge clk) begin
|
||||
tx_random_data[ii*8+:8] <= $urandom();
|
||||
end
|
||||
|
||||
assign tx_data[ii*8+:8] = DATA_RANDOM ? tx_random_data[ii*8+:8] : {tx_counter, ii_sig};
|
||||
assign rx_ref_data[ii*8+:8] = {rx_counter, ii_sig};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] phy_data_out;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] phy_charisk_out;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] phy_data_delayed;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] phy_charisk_delayed;
|
||||
reg [NUM_LANES*DATA_PATH_WIDTH*8-1:0] phy_data_in;
|
||||
reg [NUM_LANES*DATA_PATH_WIDTH-1:0] phy_charisk_in;
|
||||
|
||||
reg align_err_mf;
|
||||
reg align_err_f;
|
||||
reg cur_err;
|
||||
|
||||
reg [5:0] sysref_counter = 'h00;
|
||||
reg [9:0] sysref_counter = 'h00;
|
||||
reg sysref_rx = 1'b0;
|
||||
reg sysref_tx = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sysref_counter == 'h2f)
|
||||
if (sysref_counter == (SYSREF_HALF_COUNT-1)) begin
|
||||
sysref_rx <= ~sysref_rx;
|
||||
sysref_counter <= 'b0;
|
||||
end else begin
|
||||
sysref_counter <= sysref_counter + 1'b1;
|
||||
end
|
||||
sysref_tx <= sysref_rx;
|
||||
end
|
||||
|
||||
localparam MAX_LANE_DELAY = LANE_DELAY + NUM_LANES;
|
||||
|
||||
reg [10:0] phy_delay_fifo_wr;
|
||||
reg [36*NUM_LANES-1:0] phy_delay_fifo[0:MAX_LANE_DELAY-1];
|
||||
reg [DATA_PATH_WIDTH*9*NUM_LANES-1:0] phy_delay_fifo[0:MAX_LANE_DELAY-1];
|
||||
|
||||
always @(posedge clk) begin
|
||||
phy_delay_fifo[phy_delay_fifo_wr] <= {phy_charisk_out,phy_data_out};
|
||||
|
@ -156,6 +187,7 @@ module frame_align_tb;
|
|||
align_err_f = 1'b0;
|
||||
align_err_mf = 1'b0;
|
||||
#100000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
@ -169,10 +201,10 @@ module frame_align_tb;
|
|||
genvar i;
|
||||
generate for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
localparam OFF = MAX_LANE_DELAY - (i + LANE_DELAY);
|
||||
assign phy_data_delayed[32*i+31:32*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][32*i+31:32*i];
|
||||
assign phy_charisk_delayed[4*i+3:4*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][4*i+3+NUM_LANES*32:4*i+32*NUM_LANES];
|
||||
assign phy_data_delayed[DATA_PATH_WIDTH*8*i+(DATA_PATH_WIDTH*8)-1:DATA_PATH_WIDTH*8*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][DATA_PATH_WIDTH*8*i+(DATA_PATH_WIDTH*8)-1:DATA_PATH_WIDTH*8*i];
|
||||
assign phy_charisk_delayed[DATA_PATH_WIDTH*i+DATA_PATH_WIDTH-1:DATA_PATH_WIDTH*i]=
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][DATA_PATH_WIDTH*i+DATA_PATH_WIDTH-1+NUM_LANES*DATA_PATH_WIDTH*8:DATA_PATH_WIDTH*i+DATA_PATH_WIDTH*8*NUM_LANES];
|
||||
end endgenerate
|
||||
|
||||
always @(*) begin
|
||||
|
@ -193,7 +225,7 @@ module frame_align_tb;
|
|||
|
||||
wire [NUM_LANES-1:0] tx_cfg_lanes_disable;
|
||||
wire [NUM_LINKS-1:0] tx_cfg_links_disable;
|
||||
wire [7:0] tx_cfg_beats_per_multiframe;
|
||||
wire [9:0] tx_cfg_octets_per_multiframe;
|
||||
wire [7:0] tx_cfg_octets_per_frame;
|
||||
wire [7:0] tx_cfg_lmfc_offset;
|
||||
wire tx_cfg_sysref_disable;
|
||||
|
@ -204,23 +236,39 @@ module frame_align_tb;
|
|||
wire [7:0] tx_cfg_mframes_per_ilas;
|
||||
wire tx_cfg_disable_char_replacement;
|
||||
wire tx_cfg_disable_scrambler;
|
||||
wire tx_lmfc_edge;
|
||||
wire tx_lmfc_clk;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_eof;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_sof;
|
||||
|
||||
wire tx_ilas_config_rd;
|
||||
wire [1:0] tx_ilas_config_addr;
|
||||
wire [32*NUM_LANES-1:0] tx_ilas_config_data;
|
||||
wire [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_ilas_config_data;
|
||||
wire tx_event_sysref_edge;
|
||||
wire tx_event_sysref_alignment_error;
|
||||
wire [NUM_LINKS-1:0] tx_status_sync;
|
||||
wire [1:0] tx_status_state;
|
||||
|
||||
jesd204_tx_static_config #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.OCTETS_PER_FRAME(OCTETS_PER_FRAME),
|
||||
.FRAMES_PER_MULTIFRAME(FRAMES_PER_MULTIFRAME),
|
||||
.SCR(ENABLE_SCRAMBLER)
|
||||
.NUM_CONVERTERS(NUM_CONVERTERS),
|
||||
.N(N),
|
||||
.NP(NP),
|
||||
.HIGH_DENSITY(HIGH_DENSITY),
|
||||
.SCR(ENABLE_SCRAMBLER),
|
||||
.LINK_MODE(1),
|
||||
.SYSREF_DISABLE(SYSREF_DISABLE),
|
||||
.SYSREF_ONE_SHOT(SYSREF_ONE_SHOT),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_tx_cfg (
|
||||
.clk(clk),
|
||||
|
||||
.cfg_lanes_disable(tx_cfg_lanes_disable),
|
||||
.cfg_links_disable(tx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(tx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(tx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(tx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(tx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(tx_cfg_sysref_disable),
|
||||
|
@ -239,14 +287,33 @@ module frame_align_tb;
|
|||
|
||||
jesd204_tx #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS)
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.NUM_OUTPUT_PIPELINE(0),
|
||||
.LINK_MODE(1),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_tx (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_out),
|
||||
.phy_charisk(phy_charisk_out),
|
||||
.phy_header(),
|
||||
|
||||
.sysref(sysref_tx),
|
||||
.lmfc_edge(tx_lmfc_edge),
|
||||
.lmfc_clk(tx_lmfc_clk),
|
||||
|
||||
.sync(sync),
|
||||
|
||||
.tx_data({NUM_LANES{tx_data}}),
|
||||
.tx_ready(tx_ready),
|
||||
.tx_eof(tx_eof),
|
||||
.tx_sof(tx_sof),
|
||||
.tx_valid(1'b1),
|
||||
|
||||
.cfg_lanes_disable(tx_cfg_lanes_disable),
|
||||
.cfg_links_disable(tx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(tx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(tx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(tx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(tx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(tx_cfg_sysref_disable),
|
||||
|
@ -264,23 +331,21 @@ module frame_align_tb;
|
|||
|
||||
.ctrl_manual_sync_request(1'b0),
|
||||
|
||||
.tx_ready(tx_ready),
|
||||
.tx_data({NUM_LANES{tx_data}}),
|
||||
|
||||
.sync(sync),
|
||||
.sysref(sysref_tx),
|
||||
.event_sysref_edge (tx_event_sysref_edge),
|
||||
.event_sysref_alignment_error (tx_event_sysref_alignment_error),
|
||||
|
||||
.phy_data(phy_data_out),
|
||||
.phy_charisk(phy_charisk_out)
|
||||
.status_sync (tx_status_sync),
|
||||
.status_state (tx_status_state)
|
||||
);
|
||||
|
||||
wire [NUM_LANES-1:0] rx_cfg_lanes_disable;
|
||||
wire [NUM_LINKS-1:0] rx_cfg_links_disable;
|
||||
wire [7:0] rx_cfg_beats_per_multiframe;
|
||||
wire [9:0] rx_cfg_octets_per_multiframe;
|
||||
wire [7:0] rx_cfg_octets_per_frame;
|
||||
wire [7:0] rx_cfg_lmfc_offset;
|
||||
wire rx_sysref_disable;
|
||||
wire rx_sysref_oneshot;
|
||||
wire rx_cfg_sysref_disable;
|
||||
wire rx_cfg_sysref_oneshot;
|
||||
wire rx_cfg_disable_scrambler;
|
||||
wire rx_cfg_disable_char_replacement;
|
||||
wire rx_cfg_buffer_early_release;
|
||||
|
@ -289,19 +354,35 @@ module frame_align_tb;
|
|||
wire [NUM_LANES*14-1:0] rx_status_lane_latency;
|
||||
wire [NUM_LANES*8-1:0] rx_status_lane_frame_align_err_cnt;
|
||||
wire [7:0] rx_cfg_frame_align_err_threshold;
|
||||
wire [32*NUM_LANES-1:0] rx_status_err_statistics_cnt;
|
||||
wire rx_lmfc_edge;
|
||||
wire rx_lmfc_clk;
|
||||
wire rx_event_sysref_alignment_error;
|
||||
wire rx_event_sysref_edge;
|
||||
wire [NUM_LANES-1:0] rx_ilas_config_valid;
|
||||
wire [NUM_LANES*2-1:0] rx_ilas_config_addr;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_ilas_config_data;
|
||||
wire [1:0] rx_status_ctrl_state;
|
||||
wire [2*NUM_LANES-1:0] rx_status_lane_cgs_state;
|
||||
wire rx_phy_en_char_align;
|
||||
|
||||
jesd204_rx_static_config #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.OCTETS_PER_FRAME(OCTETS_PER_FRAME),
|
||||
.FRAMES_PER_MULTIFRAME(FRAMES_PER_MULTIFRAME),
|
||||
.SCR(ENABLE_SCRAMBLER),
|
||||
.BUFFER_EARLY_RELEASE(BUFFER_EARLY_RELEASE)
|
||||
.BUFFER_EARLY_RELEASE(BUFFER_EARLY_RELEASE),
|
||||
.LINK_MODE(1),
|
||||
.SYSREF_DISABLE(SYSREF_DISABLE),
|
||||
.SYSREF_ONE_SHOT(SYSREF_ONE_SHOT),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_rx_cfg (
|
||||
.clk(clk),
|
||||
|
||||
.cfg_lanes_disable(rx_cfg_lanes_disable),
|
||||
.cfg_links_disable(rx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(rx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(rx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(rx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(rx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(rx_cfg_sysref_disable),
|
||||
|
@ -315,46 +396,78 @@ module frame_align_tb;
|
|||
|
||||
jesd204_rx #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.NUM_INPUT_PIPELINE(1),
|
||||
.LINK_MODE(1),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.ENABLE_FRAME_ALIGN_CHECK(1),
|
||||
.ENABLE_FRAME_ALIGN_ERR_RESET(1)
|
||||
) i_rx (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_in),
|
||||
.phy_header({2*NUM_LANES{1'b0}}),
|
||||
.phy_charisk(phy_charisk_in),
|
||||
.phy_notintable({NUM_LANES*DATA_PATH_WIDTH{1'b0}}),
|
||||
.phy_disperr({NUM_LANES*DATA_PATH_WIDTH{1'b0}}),
|
||||
.phy_block_sync({NUM_LANES{1'b0}}),
|
||||
|
||||
.sysref(sysref_rx),
|
||||
.lmfc_edge(rx_lmfc_edge),
|
||||
.lmfc_clk(rx_lmfc_clk),
|
||||
|
||||
.event_sysref_alignment_error(rx_event_sysref_alignment_error),
|
||||
.event_sysref_edge(rx_event_sysref_edge),
|
||||
|
||||
.sync(sync),
|
||||
|
||||
.phy_en_char_align(rx_phy_en_char_align),
|
||||
|
||||
.rx_data(rx_data),
|
||||
.rx_valid(rx_valid),
|
||||
.rx_eof(rx_eof),
|
||||
.rx_sof(rx_sof),
|
||||
|
||||
.cfg_lanes_disable(rx_cfg_lanes_disable),
|
||||
.cfg_links_disable(rx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(rx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(rx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(rx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(rx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(rx_cfg_sysref_disable),
|
||||
.cfg_sysref_oneshot(rx_cfg_sysref_oneshot),
|
||||
.cfg_disable_scrambler(rx_cfg_disable_scrambler),
|
||||
.cfg_disable_char_replacement(rx_cfg_disable_char_replacement),
|
||||
.cfg_buffer_delay(rx_cfg_buffer_delay),
|
||||
.cfg_buffer_early_release(rx_cfg_buffer_early_release),
|
||||
.cfg_buffer_delay(rx_cfg_buffer_delay),
|
||||
.cfg_disable_char_replacement(rx_cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler(rx_cfg_disable_scrambler),
|
||||
|
||||
.ctrl_err_statistics_reset(1'b0),
|
||||
.ctrl_err_statistics_mask(7'b0),
|
||||
|
||||
.cfg_frame_align_err_threshold(rx_cfg_frame_align_err_threshold),
|
||||
|
||||
.sync(sync),
|
||||
.sysref(sysref_rx),
|
||||
.status_err_statistics_cnt(rx_status_err_statistics_cnt),
|
||||
|
||||
.rx_data(rx_data),
|
||||
.rx_valid(rx_valid),
|
||||
.ilas_config_valid(rx_ilas_config_valid),
|
||||
.ilas_config_addr(rx_ilas_config_addr),
|
||||
.ilas_config_data(rx_ilas_config_data),
|
||||
|
||||
.phy_data(phy_data_in),
|
||||
.phy_charisk(phy_charisk_in),
|
||||
.phy_notintable({NUM_LANES{4'b0000}}),
|
||||
.phy_disperr({NUM_LANES{4'b0000}}),
|
||||
.status_ctrl_state(rx_status_ctrl_state),
|
||||
.status_lane_cgs_state(rx_status_lane_cgs_state),
|
||||
|
||||
.status_lane_ifs_ready(rx_status_lane_ifs_ready),
|
||||
.status_lane_latency(rx_status_lane_latency),
|
||||
.status_lane_emb_state(),
|
||||
.status_lane_frame_align_err_cnt(rx_status_lane_frame_align_err_cnt)
|
||||
);
|
||||
|
||||
assign cur_data_mismatch = (rx_data & rx_mask) !== ({NUM_LANES{rx_ref_data}} & rx_mask);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
data_mismatch <= 1'b0;
|
||||
end else if (rx_valid == 1'b1) begin
|
||||
if ((rx_data & rx_mask) !== ({NUM_LANES{rx_ref_data}} & rx_mask)) begin
|
||||
if (cur_data_mismatch) begin
|
||||
data_mismatch <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
@ -363,11 +476,11 @@ module frame_align_tb;
|
|||
reg [NUM_LANES-1:0] lane_latency_match;
|
||||
|
||||
generate for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
localparam LANE_OFFSET = BASE_LATENCY + LANE_DELAY + BEATS_PER_MULTIFRAME + i;
|
||||
wire [31:0] LANE_OFFSET = BASE_LATENCY + LANE_DELAY + BEATS_PER_MULTIFRAME + i;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rx_status_lane_ifs_ready[i] == 1'b1 &&
|
||||
rx_status_lane_latency[i*14+13:i*14+2] == LANE_OFFSET) begin
|
||||
rx_status_lane_latency[i*14+13:i*14+DPW_LOG2] == LANE_OFFSET) begin
|
||||
lane_latency_match[i] <= 1'b1;
|
||||
end else begin
|
||||
lane_latency_match[i] <= 1'b0;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
SOURCE="jesd204_frame_align_replace_tb.v"
|
||||
SOURCE+=" ../jesd204_common/jesd204_frame_align_replace.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// 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.”
|
||||
//
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_frame_align_replace_tb;
|
||||
|
||||
|
||||
parameter VCD_FILE = "jesd204_frame_align_replace_tb.vcd";
|
||||
`define TIMEOUT 1000000
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam DATA_PATH_WIDTH = 8;
|
||||
localparam IS_RX = 1'b1;
|
||||
|
||||
wire [7:0] cfg_octets_per_frame = 5;
|
||||
wire cfg_disable_char_replacement = 1'b0;
|
||||
wire cfg_disable_scrambler = 1'b1;
|
||||
reg [DATA_PATH_WIDTH*8-1:0] data;
|
||||
reg [DATA_PATH_WIDTH-1:0] eof;
|
||||
reg [DATA_PATH_WIDTH-1:0] eomf;
|
||||
reg [DATA_PATH_WIDTH-1:0] char_is_a;
|
||||
reg [DATA_PATH_WIDTH-1:0] char_is_f;
|
||||
wire [DATA_PATH_WIDTH*8-1:0] data_out;
|
||||
wire [DATA_PATH_WIDTH-1:0] charisk_out;
|
||||
reg [31:00] ii;
|
||||
|
||||
initial begin
|
||||
#10000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
initial begin
|
||||
forever begin
|
||||
for(ii = 0; ii < DATA_PATH_WIDTH; ii = ii + 1) begin
|
||||
eof[ii] = $urandom_range(cfg_octets_per_frame) == 0;
|
||||
eomf[ii] = $urandom_range(cfg_octets_per_frame*4) == 0;
|
||||
char_is_a[ii] = $urandom_range(cfg_octets_per_frame*2) == 0;
|
||||
char_is_f[ii] = $urandom_range(cfg_octets_per_frame*2) == 0;
|
||||
end
|
||||
data = {$urandom, $urandom};
|
||||
@(negedge clk);
|
||||
end
|
||||
end
|
||||
|
||||
jesd204_frame_align_replace #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.IS_RX (IS_RX)
|
||||
) frame_align_replace (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.cfg_disable_char_replacement (cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler (cfg_disable_scrambler),
|
||||
.data (data),
|
||||
.eof (eof),
|
||||
.rx_char_is_a (char_is_a),
|
||||
.rx_char_is_f (char_is_f),
|
||||
.tx_eomf (eomf),
|
||||
.data_out (data_out),
|
||||
.charisk_out (charisk_out)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
SOURCE="jesd204_frame_mark_tb.v"
|
||||
SOURCE+=" ../jesd204_common/jesd204_frame_mark.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source run_tb.sh
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// 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.”
|
||||
//
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_frame_mark_tb;
|
||||
|
||||
|
||||
parameter VCD_FILE = "jesd204_frame_mark_tb.vcd";
|
||||
`define TIMEOUT 1000000
|
||||
`include "tb_base.v"
|
||||
|
||||
localparam DATA_PATH_WIDTH = 8;
|
||||
|
||||
wire [9:0] cfg_octets_per_multiframe = 23;
|
||||
wire [7:0] cfg_octets_per_frame = 5;
|
||||
wire [DATA_PATH_WIDTH-1:0] sof;
|
||||
wire [DATA_PATH_WIDTH-1:0] somf;
|
||||
wire [DATA_PATH_WIDTH-1:0] eof;
|
||||
wire [DATA_PATH_WIDTH-1:0] eomf;
|
||||
|
||||
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) frame_mark (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (sof),
|
||||
.eof (eof),
|
||||
.somf (somf),
|
||||
.eomf (eomf)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
SOURCE="loopback_tb.v"
|
||||
SOURCE+=" ../jesd204_common/jesd204_lmfc.v ../jesd204_common/jesd204_scrambler.v ../jesd204_common/jesd204_eof_generator.v"
|
||||
SOURCE+=" ../jesd204_common/pipeline_stage.v"
|
||||
SOURCE+=" ../jesd204_common/pipeline_stage.v ../jesd204_common/jesd204_frame_mark.v ../jesd204_common/jesd204_frame_align_replace.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx.v ../jesd204_rx/jesd204_rx_lane.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_ilas_monitor.v ../jesd204_rx/align_mux.v ../jesd204_rx/jesd204_rx_cgs.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_ctrl.v ../jesd204_rx/elastic_buffer.v ../jesd204_rx/jesd204_lane_latency_monitor.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_frame_mark.v ../jesd204_rx/jesd204_rx_frame_align_monitor.v"
|
||||
SOURCE+=" ../jesd204_rx/jesd204_rx_frame_align.v"
|
||||
SOURCE+=" ../jesd204_rx_static_config/jesd204_rx_static_config.v"
|
||||
SOURCE+=" ../jesd204_tx/jesd204_tx.v ../jesd204_tx/jesd204_tx_ctrl.v ../jesd204_tx/jesd204_tx_lane.v"
|
||||
SOURCE+=" ../jesd204_tx_static_config/jesd204_tx_static_config.v"
|
||||
|
|
|
@ -48,25 +48,38 @@ module loopback_tb;
|
|||
parameter VCD_FILE = "loopback_tb.vcd";
|
||||
parameter NUM_LANES = 4;
|
||||
parameter NUM_LINKS = 1;
|
||||
parameter OCTETS_PER_FRAME = 4;
|
||||
parameter FRAMES_PER_MULTIFRAME = 16;
|
||||
parameter ENABLE_SCRAMBLER = 1;
|
||||
parameter OCTETS_PER_FRAME = 1;
|
||||
parameter FRAMES_PER_MULTIFRAME = 28;
|
||||
parameter NUM_CONVERTERS = 1;
|
||||
parameter N = 16;
|
||||
parameter NP = 16;
|
||||
parameter HIGH_DENSITY = 1'b0;
|
||||
parameter ENABLE_SCRAMBLER = 0;
|
||||
parameter BUFFER_EARLY_RELEASE = 1;
|
||||
parameter SYSREF_DISABLE = 0;
|
||||
parameter SYSREF_ONE_SHOT = 0;
|
||||
parameter LANE_DELAY = 1;
|
||||
parameter DATA_PATH_WIDTH = 4;
|
||||
parameter DATA_RANDOM = ENABLE_SCRAMBLER ? 0 : 1;
|
||||
|
||||
localparam DPW_LOG2 = DATA_PATH_WIDTH == 8 ? 3 : DATA_PATH_WIDTH == 4 ? 2 : 1;
|
||||
localparam BEATS_PER_MULTIFRAME = OCTETS_PER_FRAME * FRAMES_PER_MULTIFRAME / 4;
|
||||
localparam TX_LATENCY = 3;
|
||||
localparam RX_LATENCY = 3;
|
||||
localparam BASE_LATENCY = TX_LATENCY + RX_LATENCY;
|
||||
wire [31:0] RX_LATENCY = 3 + i_rx.CHAR_INFO_REGISTERED + i_rx.ALIGN_MUX_REGISTERED + i_rx.SCRAMBLER_REGISTERED;
|
||||
wire [31:0] BASE_LATENCY = TX_LATENCY + RX_LATENCY;
|
||||
localparam SYSREF_HALF_COUNT = OCTETS_PER_FRAME * FRAMES_PER_MULTIFRAME;
|
||||
|
||||
`define TIMEOUT 1000000
|
||||
`include "tb_base.v"
|
||||
|
||||
reg [5:0] tx_counter = 'h00;
|
||||
reg [5:0] rx_counter = 'h00;
|
||||
reg [NUM_LANES*32-1:0] rx_mask = 'hffff0000;
|
||||
reg [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_mask = 64'hffffffffffff0000;
|
||||
wire tx_ready;
|
||||
wire rx_valid;
|
||||
wire [NUM_LANES*32-1:0] rx_data;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_data;
|
||||
wire [DATA_PATH_WIDTH-1:0] rx_eof;
|
||||
wire [DATA_PATH_WIDTH-1:0] rx_sof;
|
||||
reg data_mismatch = 1'b1;
|
||||
wire [NUM_LINKS-1:0] sync;
|
||||
|
||||
|
@ -82,39 +95,58 @@ module loopback_tb;
|
|||
if (sync == 1'b0) begin
|
||||
rx_counter <= 'h00000000;
|
||||
if (ENABLE_SCRAMBLER == 1'b1) begin
|
||||
rx_mask <= {NUM_LANES{32'hffff0000}}; // First two octets are invalid due to scrambling
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffff0000}}; // First two octets are invalid due to scrambling
|
||||
end else begin
|
||||
rx_mask <= {NUM_LANES{32'hffffffff}};
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffffffff}};
|
||||
end
|
||||
end else if (rx_valid == 1'b1) begin
|
||||
rx_counter <= rx_counter + 1'b1;
|
||||
rx_mask <= {NUM_LANES{32'hffffffff}};
|
||||
rx_mask <= {NUM_LANES{64'hffffffffffffffff}};
|
||||
end
|
||||
end
|
||||
|
||||
wire [31:0] tx_data = {tx_counter,2'h3,tx_counter,2'h2,tx_counter,2'h1,tx_counter,2'h0};
|
||||
wire [31:0] rx_ref_data = {rx_counter,2'h3,rx_counter,2'h2,rx_counter,2'h1,rx_counter,2'h0};
|
||||
|
||||
wire [NUM_LANES*32-1:0] phy_data_out;
|
||||
wire [NUM_LANES*4-1:0] phy_charisk_out;
|
||||
wire [NUM_LANES*32-1:0] phy_data_in;
|
||||
wire [NUM_LANES*4-1:0] phy_charisk_in;
|
||||
reg [(DATA_PATH_WIDTH*8)-1:0] tx_random_data;
|
||||
wire [(DATA_PATH_WIDTH*8)-1:0] tx_data;
|
||||
wire [(DATA_PATH_WIDTH*8)-1:0] rx_ref_data;
|
||||
|
||||
reg [5:0] sysref_counter = 'h00;
|
||||
genvar ii;
|
||||
generate
|
||||
for(ii = 0; ii < DATA_PATH_WIDTH; ii=ii+1) begin : data_gen
|
||||
wire [1:0] ii_sig = ii;
|
||||
|
||||
always @(posedge clk) begin
|
||||
tx_random_data[ii*8+:8] <= $urandom();
|
||||
end
|
||||
|
||||
assign tx_data[ii*8+:8] = DATA_RANDOM ? tx_random_data[ii*8+:8] : {tx_counter, ii_sig};
|
||||
assign rx_ref_data[ii*8+:8] = {rx_counter, ii_sig};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] phy_data_out;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] phy_charisk_out;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] phy_data_in;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH-1:0] phy_charisk_in;
|
||||
|
||||
reg [9:0] sysref_counter = 'h00;
|
||||
reg sysref_rx = 1'b0;
|
||||
reg sysref_tx = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sysref_counter == 'h2f)
|
||||
if (sysref_counter == (SYSREF_HALF_COUNT-1)) begin
|
||||
sysref_rx <= ~sysref_rx;
|
||||
sysref_counter <= sysref_counter + 1'b1;
|
||||
sysref_counter <= 'b0;
|
||||
end else begin
|
||||
sysref_counter <= sysref_counter + 1'b1;
|
||||
end
|
||||
sysref_tx <= sysref_rx;
|
||||
end
|
||||
|
||||
localparam MAX_LANE_DELAY = LANE_DELAY + NUM_LANES;
|
||||
|
||||
reg [10:0] phy_delay_fifo_wr;
|
||||
reg [36*NUM_LANES-1:0] phy_delay_fifo[0:MAX_LANE_DELAY-1];
|
||||
reg [DATA_PATH_WIDTH*9*NUM_LANES-1:0] phy_delay_fifo[0:MAX_LANE_DELAY-1];
|
||||
|
||||
always @(posedge clk) begin
|
||||
phy_delay_fifo[phy_delay_fifo_wr] <= {phy_charisk_out,phy_data_out};
|
||||
|
@ -129,15 +161,15 @@ module loopback_tb;
|
|||
genvar i;
|
||||
generate for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
localparam OFF = MAX_LANE_DELAY - (i + LANE_DELAY);
|
||||
assign phy_data_in[32*i+31:32*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][32*i+31:32*i];
|
||||
assign phy_charisk_in[4*i+3:4*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][4*i+3+NUM_LANES*32:4*i+32*NUM_LANES];
|
||||
assign phy_data_in[DATA_PATH_WIDTH*8*i+(DATA_PATH_WIDTH*8)-1:DATA_PATH_WIDTH*8*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][DATA_PATH_WIDTH*8*i+(DATA_PATH_WIDTH*8)-1:DATA_PATH_WIDTH*8*i];
|
||||
assign phy_charisk_in[DATA_PATH_WIDTH*i+DATA_PATH_WIDTH-1:DATA_PATH_WIDTH*i] =
|
||||
phy_delay_fifo[(phy_delay_fifo_wr + OFF) % MAX_LANE_DELAY][DATA_PATH_WIDTH*i+DATA_PATH_WIDTH-1+NUM_LANES*DATA_PATH_WIDTH*8:DATA_PATH_WIDTH*i+DATA_PATH_WIDTH*8*NUM_LANES];
|
||||
end endgenerate
|
||||
|
||||
wire [NUM_LANES-1:0] tx_cfg_lanes_disable;
|
||||
wire [NUM_LINKS-1:0] tx_cfg_links_disable;
|
||||
wire [7:0] tx_cfg_beats_per_multiframe;
|
||||
wire [9:0] tx_cfg_octets_per_multiframe;
|
||||
wire [7:0] tx_cfg_octets_per_frame;
|
||||
wire [7:0] tx_cfg_lmfc_offset;
|
||||
wire tx_cfg_sysref_disable;
|
||||
|
@ -148,23 +180,39 @@ module loopback_tb;
|
|||
wire [7:0] tx_cfg_mframes_per_ilas;
|
||||
wire tx_cfg_disable_char_replacement;
|
||||
wire tx_cfg_disable_scrambler;
|
||||
wire tx_lmfc_edge;
|
||||
wire tx_lmfc_clk;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_eof;
|
||||
wire [DATA_PATH_WIDTH-1:0] tx_sof;
|
||||
|
||||
wire tx_ilas_config_rd;
|
||||
wire [1:0] tx_ilas_config_addr;
|
||||
wire [32*NUM_LANES-1:0] tx_ilas_config_data;
|
||||
wire [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_ilas_config_data;
|
||||
wire tx_event_sysref_edge;
|
||||
wire tx_event_sysref_alignment_error;
|
||||
wire [NUM_LINKS-1:0] tx_status_sync;
|
||||
wire [1:0] tx_status_state;
|
||||
|
||||
jesd204_tx_static_config #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.OCTETS_PER_FRAME(OCTETS_PER_FRAME),
|
||||
.FRAMES_PER_MULTIFRAME(FRAMES_PER_MULTIFRAME),
|
||||
.SCR(ENABLE_SCRAMBLER)
|
||||
.NUM_CONVERTERS(NUM_CONVERTERS),
|
||||
.N(N),
|
||||
.NP(NP),
|
||||
.HIGH_DENSITY(HIGH_DENSITY),
|
||||
.SCR(ENABLE_SCRAMBLER),
|
||||
.LINK_MODE(1),
|
||||
.SYSREF_DISABLE(SYSREF_DISABLE),
|
||||
.SYSREF_ONE_SHOT(SYSREF_ONE_SHOT),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_tx_cfg (
|
||||
.clk(clk),
|
||||
|
||||
.cfg_lanes_disable(tx_cfg_lanes_disable),
|
||||
.cfg_links_disable(tx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(tx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(tx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(tx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(tx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(tx_cfg_sysref_disable),
|
||||
|
@ -183,14 +231,33 @@ module loopback_tb;
|
|||
|
||||
jesd204_tx #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS)
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.NUM_OUTPUT_PIPELINE(0),
|
||||
.LINK_MODE(1),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_tx (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_out),
|
||||
.phy_charisk(phy_charisk_out),
|
||||
.phy_header(),
|
||||
|
||||
.sysref(sysref_tx),
|
||||
.lmfc_edge(tx_lmfc_edge),
|
||||
.lmfc_clk(tx_lmfc_clk),
|
||||
|
||||
.sync(sync),
|
||||
|
||||
.tx_data({NUM_LANES{tx_data}}),
|
||||
.tx_ready(tx_ready),
|
||||
.tx_eof(tx_eof),
|
||||
.tx_sof(tx_sof),
|
||||
.tx_valid(1'b1),
|
||||
|
||||
.cfg_lanes_disable(tx_cfg_lanes_disable),
|
||||
.cfg_links_disable(tx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(tx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(tx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(tx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(tx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(tx_cfg_sysref_disable),
|
||||
|
@ -208,63 +275,57 @@ module loopback_tb;
|
|||
|
||||
.ctrl_manual_sync_request(1'b0),
|
||||
|
||||
.tx_ready(tx_ready),
|
||||
.tx_data({NUM_LANES{tx_data}}),
|
||||
.event_sysref_edge (tx_event_sysref_edge),
|
||||
.event_sysref_alignment_error (tx_event_sysref_alignment_error),
|
||||
|
||||
.sync(sync),
|
||||
.sysref(sysref_tx),
|
||||
|
||||
.phy_data(phy_data_out),
|
||||
.phy_charisk(phy_charisk_out)
|
||||
.status_sync (tx_status_sync),
|
||||
.status_state (tx_status_state)
|
||||
);
|
||||
|
||||
wire [NUM_LANES-1:0] rx_cfg_lanes_disable;
|
||||
wire [NUM_LINKS-1:0] rx_cfg_links_disable;
|
||||
wire [7:0] rx_cfg_beats_per_multiframe;
|
||||
wire [9:0] rx_cfg_octets_per_multiframe;
|
||||
wire [7:0] rx_cfg_octets_per_frame;
|
||||
wire [7:0] rx_cfg_lmfc_offset;
|
||||
wire rx_sysref_disable;
|
||||
wire rx_sysref_oneshot;
|
||||
wire rx_cfg_sysref_disable;
|
||||
wire rx_cfg_sysref_oneshot;
|
||||
wire rx_cfg_disable_scrambler;
|
||||
wire rx_cfg_disable_char_replacement;
|
||||
wire rx_cfg_buffer_early_release;
|
||||
wire [7:0] rx_cfg_buffer_delay;
|
||||
wire [NUM_LANES-1:0] rx_status_lane_ifs_ready;
|
||||
wire [NUM_LANES*14-1:0] rx_status_lane_latency;
|
||||
wire [NUM_LANES*32-1:0] rx_status_lane_frame_align_err_cnt;
|
||||
wire [31:0] rx_cfg_frame_align_err_threshold = 32'd4; // TODO: static config
|
||||
wire [NUM_LANES*8-1:0] rx_status_lane_frame_align_err_cnt;
|
||||
wire [7:0] rx_cfg_frame_align_err_threshold;
|
||||
wire [32*NUM_LANES-1:0] rx_status_err_statistics_cnt;
|
||||
wire rx_lmfc_edge;
|
||||
wire rx_lmfc_clk;
|
||||
wire rx_event_sysref_alignment_error;
|
||||
wire rx_event_sysref_edge;
|
||||
wire [NUM_LANES-1:0] rx_ilas_config_valid;
|
||||
wire [NUM_LANES*2-1:0] rx_ilas_config_addr;
|
||||
wire [NUM_LANES*DATA_PATH_WIDTH*8-1:0] rx_ilas_config_data;
|
||||
wire [1:0] rx_status_ctrl_state;
|
||||
wire [2*NUM_LANES-1:0] rx_status_lane_cgs_state;
|
||||
wire rx_phy_en_char_align;
|
||||
|
||||
jesd204_rx_static_config #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.OCTETS_PER_FRAME(OCTETS_PER_FRAME),
|
||||
.FRAMES_PER_MULTIFRAME(FRAMES_PER_MULTIFRAME),
|
||||
.SCR(ENABLE_SCRAMBLER),
|
||||
.BUFFER_EARLY_RELEASE(BUFFER_EARLY_RELEASE)
|
||||
.BUFFER_EARLY_RELEASE(BUFFER_EARLY_RELEASE),
|
||||
.LINK_MODE(1),
|
||||
.SYSREF_DISABLE(SYSREF_DISABLE),
|
||||
.SYSREF_ONE_SHOT(SYSREF_ONE_SHOT),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_rx_cfg (
|
||||
.clk(clk),
|
||||
|
||||
.cfg_lanes_disable(rx_cfg_lanes_disable),
|
||||
.cfg_links_disable(rx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(rx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_frame(rx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(rx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(rx_cfg_sysref_disable),
|
||||
.cfg_sysref_oneshot(rx_cfg_sysref_oneshot),
|
||||
.cfg_disable_scrambler(rx_cfg_disable_scrambler),
|
||||
.cfg_disable_char_replacement(rx_cfg_disable_char_replacement),
|
||||
.cfg_buffer_delay(rx_cfg_buffer_delay),
|
||||
.cfg_buffer_early_release(rx_cfg_buffer_early_release)
|
||||
);
|
||||
|
||||
jesd204_rx #(
|
||||
.NUM_LANES(NUM_LANES)
|
||||
) i_rx (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.cfg_lanes_disable(rx_cfg_lanes_disable),
|
||||
.cfg_links_disable(rx_cfg_links_disable),
|
||||
.cfg_beats_per_multiframe(rx_cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_multiframe(rx_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame(rx_cfg_octets_per_frame),
|
||||
.cfg_lmfc_offset(rx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(rx_cfg_sysref_disable),
|
||||
|
@ -273,21 +334,72 @@ module loopback_tb;
|
|||
.cfg_disable_char_replacement(rx_cfg_disable_char_replacement),
|
||||
.cfg_buffer_delay(rx_cfg_buffer_delay),
|
||||
.cfg_buffer_early_release(rx_cfg_buffer_early_release),
|
||||
.cfg_frame_align_err_threshold(rx_cfg_frame_align_err_threshold),
|
||||
.cfg_frame_align_err_threshold(rx_cfg_frame_align_err_threshold)
|
||||
);
|
||||
|
||||
jesd204_rx #(
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.NUM_LINKS(NUM_LINKS),
|
||||
.NUM_INPUT_PIPELINE(1),
|
||||
.LINK_MODE(1),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.ENABLE_FRAME_ALIGN_CHECK(1),
|
||||
.ENABLE_FRAME_ALIGN_ERR_RESET(1)
|
||||
) i_rx (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.phy_data(phy_data_in),
|
||||
.phy_header({2*NUM_LANES{1'b0}}),
|
||||
.phy_charisk(phy_charisk_in),
|
||||
.phy_notintable({NUM_LANES*DATA_PATH_WIDTH{1'b0}}),
|
||||
.phy_disperr({NUM_LANES*DATA_PATH_WIDTH{1'b0}}),
|
||||
.phy_block_sync({NUM_LANES{1'b0}}),
|
||||
|
||||
.sysref(sysref_rx),
|
||||
.lmfc_edge(rx_lmfc_edge),
|
||||
.lmfc_clk(rx_lmfc_clk),
|
||||
|
||||
.event_sysref_alignment_error(rx_event_sysref_alignment_error),
|
||||
.event_sysref_edge(rx_event_sysref_edge),
|
||||
|
||||
.sync(sync),
|
||||
.sysref(sysref_rx),
|
||||
|
||||
.phy_en_char_align(rx_phy_en_char_align),
|
||||
|
||||
.rx_data(rx_data),
|
||||
.rx_valid(rx_valid),
|
||||
.rx_eof(rx_eof),
|
||||
.rx_sof(rx_sof),
|
||||
|
||||
.phy_data(phy_data_in),
|
||||
.phy_charisk(phy_charisk_in),
|
||||
.phy_notintable({NUM_LANES{4'b0000}}),
|
||||
.phy_disperr({NUM_LANES{4'b0000}}),
|
||||
.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),
|
||||
.cfg_lmfc_offset(rx_cfg_lmfc_offset),
|
||||
.cfg_sysref_disable(rx_cfg_sysref_disable),
|
||||
.cfg_sysref_oneshot(rx_cfg_sysref_oneshot),
|
||||
.cfg_buffer_early_release(rx_cfg_buffer_early_release),
|
||||
.cfg_buffer_delay(rx_cfg_buffer_delay),
|
||||
.cfg_disable_char_replacement(rx_cfg_disable_char_replacement),
|
||||
.cfg_disable_scrambler(rx_cfg_disable_scrambler),
|
||||
|
||||
.ctrl_err_statistics_reset(1'b0),
|
||||
.ctrl_err_statistics_mask(7'b0),
|
||||
|
||||
.cfg_frame_align_err_threshold(rx_cfg_frame_align_err_threshold),
|
||||
|
||||
.status_err_statistics_cnt(rx_status_err_statistics_cnt),
|
||||
|
||||
.ilas_config_valid(rx_ilas_config_valid),
|
||||
.ilas_config_addr(rx_ilas_config_addr),
|
||||
.ilas_config_data(rx_ilas_config_data),
|
||||
|
||||
.status_ctrl_state(rx_status_ctrl_state),
|
||||
.status_lane_cgs_state(rx_status_lane_cgs_state),
|
||||
.status_lane_ifs_ready(rx_status_lane_ifs_ready),
|
||||
.status_lane_latency(rx_status_lane_latency),
|
||||
.status_lane_emb_state(),
|
||||
.status_lane_frame_align_err_cnt(rx_status_lane_frame_align_err_cnt)
|
||||
);
|
||||
|
||||
|
@ -304,11 +416,11 @@ module loopback_tb;
|
|||
reg [NUM_LANES-1:0] lane_latency_match;
|
||||
|
||||
generate for (i = 0; i < NUM_LANES; i = i + 1) begin
|
||||
localparam LANE_OFFSET = BASE_LATENCY + LANE_DELAY + BEATS_PER_MULTIFRAME + i;
|
||||
wire [31:0] LANE_OFFSET = BASE_LATENCY + LANE_DELAY + BEATS_PER_MULTIFRAME + i;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rx_status_lane_ifs_ready[i] == 1'b1 &&
|
||||
rx_status_lane_latency[i*14+13:i*14+2] == LANE_OFFSET) begin
|
||||
rx_status_lane_latency[i*14+13:i*14+DPW_LOG2] == LANE_OFFSET) begin
|
||||
lane_latency_match[i] <= 1'b1;
|
||||
end else begin
|
||||
lane_latency_match[i] <= 1'b0;
|
||||
|
|
|
@ -11,7 +11,7 @@ case "$SIMULATOR" in
|
|||
# Xcelium flow
|
||||
xmvlog -NOWARN NONPRT ${SOURCE} || exit 1
|
||||
xmelab -access +rc ${NAME}
|
||||
xmsim ${NAME} -run -gui || exit 1
|
||||
xmsim ${NAME} -gui || exit 1
|
||||
;;
|
||||
xsim)
|
||||
# xsim flow
|
||||
|
|
Loading…
Reference in New Issue