jesd204: Xilinx: NP=12 support
To support deterministic latency with non-power of two octets per frame (F=3,6) the interface width towards the transport layer must be resized to match integer multiple of frames. e.g Input datapath width = 4; Output datpath width = 6; for F=3 one beat contains 2 frames for F=6 one beat contains 1 frame The width change is realized with a gearbox. Due the interface width change the single clock domain core is split in two clock domains. - Link clock : lane rate / 40 for input datapath width of 4 octets 8b10b - lane rate / 20 for input datapath width of 8 octets 8b10b - lane rate / 66 for input datapath width of 8 octets 64b66b - Device clock : Link clock * input data path width / output datapath width Interface to transport layer and SYSREF handling is moved to device clock domain. The configuration interface reflects the dual clock domain. If Input and Output datapath width matches, the gearbox is no longer required, a single clock can be connected to both clocks.main
parent
e909962fb0
commit
454b900f90
|
@ -34,6 +34,7 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
parameter SAMPLES_PER_FRAME = 1,
|
||||
parameter CONVERTER_RESOLUTION = 14,
|
||||
parameter BITS_PER_SAMPLE = 16,
|
||||
parameter DMA_BITS_PER_SAMPLE = 16,
|
||||
parameter OCTETS_PER_BEAT = 4,
|
||||
parameter TWOS_COMPLEMENT = 1
|
||||
) (
|
||||
|
@ -51,7 +52,7 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
output [NUM_CHANNELS-1:0] enable,
|
||||
|
||||
output [NUM_CHANNELS-1:0] adc_valid,
|
||||
output [NUM_LANES*8*OCTETS_PER_BEAT-1:0] adc_data,
|
||||
output [DMA_BITS_PER_SAMPLE * OCTETS_PER_BEAT * 8 * NUM_LANES / BITS_PER_SAMPLE-1:0] adc_data,
|
||||
input adc_dovf,
|
||||
|
||||
input adc_sync_in,
|
||||
|
@ -90,7 +91,7 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
// Number of samples per channel that are processed in parallel.
|
||||
localparam DATA_PATH_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES / NUM_CHANNELS / BITS_PER_SAMPLE;
|
||||
localparam LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8;
|
||||
localparam DMA_DATA_WIDTH = BITS_PER_SAMPLE * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||
localparam DMA_DATA_WIDTH = DMA_BITS_PER_SAMPLE * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||
|
||||
localparam BYTES_PER_FRAME = (NUM_CHANNELS * BITS_PER_SAMPLE * SAMPLES_PER_FRAME) / ( 8 * NUM_LANES);
|
||||
|
||||
|
@ -180,7 +181,8 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||
.DMA_DATA_WIDTH (DMA_DATA_WIDTH),
|
||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT),
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.DMA_BITS_PER_SAMPLE (DMA_BITS_PER_SAMPLE)
|
||||
) i_core (
|
||||
.clk (link_clk),
|
||||
|
||||
|
|
|
@ -29,10 +29,11 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
parameter SAMPLES_PER_FRAME = 1,
|
||||
parameter CONVERTER_RESOLUTION = 14,
|
||||
parameter BITS_PER_SAMPLE = 16,
|
||||
parameter DMA_BITS_PER_SAMPLE = 16,
|
||||
parameter OCTETS_PER_BEAT = 4,
|
||||
parameter DATA_PATH_WIDTH = 1,
|
||||
parameter LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8,
|
||||
parameter DMA_DATA_WIDTH = DATA_PATH_WIDTH * BITS_PER_SAMPLE * NUM_CHANNELS,
|
||||
parameter DMA_DATA_WIDTH = DATA_PATH_WIDTH * DMA_BITS_PER_SAMPLE * NUM_CHANNELS,
|
||||
parameter TWOS_COMPLEMENT = 1
|
||||
) (
|
||||
input clk,
|
||||
|
@ -61,7 +62,7 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
// Raw and formatted channel data widths
|
||||
localparam CDW_RAW = CONVERTER_RESOLUTION * DATA_PATH_WIDTH;
|
||||
localparam ADC_DATA_WIDTH = CDW_RAW * NUM_CHANNELS;
|
||||
localparam CDW_FMT = BITS_PER_SAMPLE * DATA_PATH_WIDTH;
|
||||
localparam CDW_FMT = DMA_BITS_PER_SAMPLE * DATA_PATH_WIDTH;
|
||||
|
||||
wire [ADC_DATA_WIDTH-1:0] raw_data_s;
|
||||
|
||||
|
@ -109,7 +110,7 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT),
|
||||
.BITS_PER_SAMPLE (BITS_PER_SAMPLE)
|
||||
.BITS_PER_SAMPLE (DMA_BITS_PER_SAMPLE)
|
||||
) i_channel (
|
||||
.clk (clk),
|
||||
|
||||
|
|
|
@ -74,9 +74,10 @@ foreach {p v} {
|
|||
"NUM_LANES" "1 2 3 4 8 16" \
|
||||
"NUM_CHANNELS" "1 2 4 6 8 16 32 64" \
|
||||
"BITS_PER_SAMPLE" "8 12 16" \
|
||||
"DMA_BITS_PER_SAMPLE" "8 12 16" \
|
||||
"CONVERTER_RESOLUTION" "8 11 12 16" \
|
||||
"SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \
|
||||
"OCTETS_PER_BEAT" "4 8" \
|
||||
"OCTETS_PER_BEAT" "4 6 8 12" \
|
||||
} { \
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "list" \
|
||||
|
@ -104,6 +105,7 @@ foreach {k v} { \
|
|||
"NUM_LANES" "Number of Lanes (L)" \
|
||||
"NUM_CHANNELS" "Number of Conveters (M)" \
|
||||
"BITS_PER_SAMPLE" "Bits per Sample (N')" \
|
||||
"DMA_BITS_PER_SAMPLE" "DMA Bits per Sample" \
|
||||
"CONVERTER_RESOLUTION" "Converter Resolution (N)" \
|
||||
"SAMPLES_PER_FRAME" "Samples per Frame (S)" \
|
||||
"OCTETS_PER_BEAT" "Octets per Beat" \
|
||||
|
|
|
@ -32,8 +32,9 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
parameter NUM_LANES = 4,
|
||||
parameter NUM_CHANNELS = 2,
|
||||
parameter SAMPLES_PER_FRAME = 1,
|
||||
parameter CONVERTER_RESOLUTION = 16,
|
||||
parameter BITS_PER_SAMPLE = 16,
|
||||
parameter CONVERTER_RESOLUTION = 16, // JESD_N
|
||||
parameter BITS_PER_SAMPLE = 16, // JESD_NP
|
||||
parameter DMA_BITS_PER_SAMPLE = 16,
|
||||
parameter OCTETS_PER_BEAT = 4,
|
||||
parameter DDS_TYPE = 1,
|
||||
parameter DDS_CORDIC_DW = 16,
|
||||
|
@ -55,7 +56,7 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
output [NUM_CHANNELS-1:0] enable,
|
||||
|
||||
output [NUM_CHANNELS-1:0] dac_valid,
|
||||
input [NUM_LANES*8*OCTETS_PER_BEAT-1:0] dac_ddata,
|
||||
input [DMA_BITS_PER_SAMPLE * OCTETS_PER_BEAT * 8 * NUM_LANES / BITS_PER_SAMPLE-1:0] dac_ddata,
|
||||
input dac_dunf,
|
||||
|
||||
// external sync, should be on the link_clk clock domain
|
||||
|
@ -94,7 +95,7 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
|
||||
localparam DATA_PATH_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES / NUM_CHANNELS / BITS_PER_SAMPLE;
|
||||
localparam LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8;
|
||||
localparam DMA_DATA_WIDTH = BITS_PER_SAMPLE * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||
localparam DMA_DATA_WIDTH = DMA_BITS_PER_SAMPLE * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||
|
||||
localparam BYTES_PER_FRAME = (NUM_CHANNELS * BITS_PER_SAMPLE * SAMPLES_PER_FRAME) / ( 8 * NUM_LANES);
|
||||
|
||||
|
@ -119,6 +120,8 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
wire [NUM_CHANNELS*16-1:0] dac_iqcor_coeff_2;
|
||||
wire [NUM_CHANNELS*8-1:0] dac_src_chan_sel;
|
||||
|
||||
reg [LINK_DATA_WIDTH-1:0] dac_ddata_cr;
|
||||
|
||||
// regmap
|
||||
|
||||
ad_ip_jesd204_tpl_dac_regmap #(
|
||||
|
@ -205,7 +208,6 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||
.DMA_DATA_WIDTH (DMA_DATA_WIDTH),
|
||||
.DDS_TYPE (DDS_TYPE),
|
||||
.DDS_CORDIC_DW (DDS_CORDIC_DW),
|
||||
.DDS_CORDIC_PHASE_DW (DDS_CORDIC_PHASE_DW),
|
||||
|
@ -220,7 +222,7 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
.enable (enable),
|
||||
|
||||
.dac_valid (dac_valid),
|
||||
.dac_ddata (dac_ddata),
|
||||
.dac_ddata (dac_ddata_cr),
|
||||
|
||||
.dac_sync (dac_sync),
|
||||
.dac_sync_in_status (dac_sync_in_status),
|
||||
|
@ -246,4 +248,12 @@ module ad_ip_jesd204_tpl_dac #(
|
|||
|
||||
);
|
||||
|
||||
// Drop DMA padding bits from the MSB
|
||||
integer i;
|
||||
always @(*) begin
|
||||
for (i=0;i<NUM_CHANNELS*DATA_PATH_WIDTH;i=i+1) begin
|
||||
dac_ddata_cr[i*BITS_PER_SAMPLE +: BITS_PER_SAMPLE] = dac_ddata[i*DMA_BITS_PER_SAMPLE +: BITS_PER_SAMPLE];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -35,7 +35,6 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
parameter OCTETS_PER_BEAT = 4,
|
||||
parameter DATA_PATH_WIDTH = 4,
|
||||
parameter LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8,
|
||||
parameter DMA_DATA_WIDTH = DATA_PATH_WIDTH * BITS_PER_SAMPLE * NUM_CHANNELS,
|
||||
parameter DDS_TYPE = 1,
|
||||
parameter DDS_CORDIC_DW = 16,
|
||||
parameter DDS_CORDIC_PHASE_DW = 16,
|
||||
|
@ -50,7 +49,7 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
|
||||
// dma interface
|
||||
output [NUM_CHANNELS-1:0] dac_valid,
|
||||
input [DMA_DATA_WIDTH-1:0] dac_ddata,
|
||||
input [LINK_DATA_WIDTH-1:0] dac_ddata,
|
||||
|
||||
// Configuration interface
|
||||
|
||||
|
@ -86,11 +85,9 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
|
||||
localparam DAC_CDW = CONVERTER_RESOLUTION * DATA_PATH_WIDTH;
|
||||
localparam DAC_DATA_WIDTH = DAC_CDW * NUM_CHANNELS;
|
||||
localparam DMA_CDW = DATA_PATH_WIDTH * BITS_PER_SAMPLE;
|
||||
|
||||
|
||||
wire [DAC_DATA_WIDTH-1:0] dac_data_s;
|
||||
wire [DMA_DATA_WIDTH-1:0] dac_ddata_muxed;
|
||||
wire [DAC_DATA_WIDTH-1:0] dac_ddata_muxed;
|
||||
|
||||
wire [DAC_CDW-1:0] pn7_data;
|
||||
wire [DAC_CDW-1:0] pn15_data;
|
||||
|
@ -158,23 +155,22 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
localparam IQ_PAIR_CH_INDEX = (NUM_CHANNELS%2) ? i :
|
||||
(i%2) ? i-1 : i+1;
|
||||
|
||||
|
||||
if (XBAR_ENABLE == 1) begin
|
||||
|
||||
// NUM_CHANNELS : 1 mux
|
||||
ad_mux #(
|
||||
.CH_W (DMA_CDW),
|
||||
.CH_W (DAC_CDW),
|
||||
.CH_CNT (NUM_CHANNELS),
|
||||
.EN_REG (1)
|
||||
) channel_mux (
|
||||
.clk (clk),
|
||||
.data_in (dac_ddata),
|
||||
.ch_sel (dac_src_chan_sel[8*i+:8]),
|
||||
.data_out (dac_ddata_muxed[DMA_CDW*i+:DMA_CDW])
|
||||
.data_out (dac_ddata_muxed[DAC_CDW*i+:DAC_CDW])
|
||||
);
|
||||
|
||||
end else begin
|
||||
assign dac_ddata_muxed[DMA_CDW*i+:DMA_CDW] = dac_ddata[DMA_CDW*i+:DMA_CDW];
|
||||
assign dac_ddata_muxed[DAC_CDW*i+:DAC_CDW] = dac_ddata[DAC_CDW*i+:DAC_CDW];
|
||||
end
|
||||
|
||||
ad_ip_jesd204_tpl_dac_channel #(
|
||||
|
@ -191,7 +187,7 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
.clk (clk),
|
||||
.dac_enable (enable[i]),
|
||||
.dac_data (dac_data_s[DAC_CDW*i+:DAC_CDW]),
|
||||
.dma_data (dac_ddata_muxed[DMA_CDW*i+:DMA_CDW]),
|
||||
.dma_data (dac_ddata_muxed[DAC_CDW*i+:DAC_CDW]),
|
||||
|
||||
.pn7_data (pn7_data),
|
||||
.pn15_data (pn15_data),
|
||||
|
@ -215,7 +211,7 @@ module ad_ip_jesd204_tpl_dac_core #(
|
|||
.dac_iqcor_enb (dac_iqcor_enb[i]),
|
||||
.dac_iqcor_coeff_1 (dac_iqcor_coeff_1[16*i+:16]),
|
||||
.dac_iqcor_coeff_2 (dac_iqcor_coeff_2[16*i+:16]),
|
||||
.dac_iqcor_data_in (dac_ddata_muxed[DMA_CDW*IQ_PAIR_CH_INDEX+:DMA_CDW])
|
||||
.dac_iqcor_data_in (dac_ddata_muxed[DAC_CDW*IQ_PAIR_CH_INDEX+:DAC_CDW])
|
||||
|
||||
);
|
||||
end
|
||||
|
|
|
@ -97,9 +97,10 @@ foreach {p v} {
|
|||
"NUM_LANES" "1 2 3 4 8 16" \
|
||||
"NUM_CHANNELS" "1 2 4 6 8 16 32 64" \
|
||||
"BITS_PER_SAMPLE" "8 12 16" \
|
||||
"DMA_BITS_PER_SAMPLE" "8 12 16" \
|
||||
"CONVERTER_RESOLUTION" "8 11 12 16" \
|
||||
"SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \
|
||||
"OCTETS_PER_BEAT" "4 8" \
|
||||
"OCTETS_PER_BEAT" "4 6 8 12" \
|
||||
} { \
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "list" \
|
||||
|
@ -127,6 +128,7 @@ foreach {k v} { \
|
|||
"NUM_LANES" "Number of Lanes (L)" \
|
||||
"NUM_CHANNELS" "Number of Conveters (M)" \
|
||||
"BITS_PER_SAMPLE" "Bits per Sample (N')" \
|
||||
"DMA_BITS_PER_SAMPLE" "DMA Bits per Sample" \
|
||||
"CONVERTER_RESOLUTION" "Converter Resolution (N)" \
|
||||
"SAMPLES_PER_FRAME" "Samples per Frame (S)" \
|
||||
"OCTETS_PER_BEAT" "Octets per Beat" \
|
||||
|
|
|
@ -51,9 +51,9 @@ module jesd204_up_common # (
|
|||
parameter NUM_LANES = 1,
|
||||
parameter NUM_LINKS = 1,
|
||||
parameter DATA_PATH_WIDTH_LOG2 = 2,
|
||||
parameter MAX_OCTETS_PER_FRAME = 256,
|
||||
parameter NUM_IRQS = 1,
|
||||
parameter EXTRA_CFG_WIDTH = 1,
|
||||
parameter DEV_EXTRA_CFG_WIDTH = 1,
|
||||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
parameter ENABLE_LINK_STATS = 0
|
||||
) (
|
||||
|
@ -68,6 +68,9 @@ module jesd204_up_common # (
|
|||
input core_reset_ext,
|
||||
output core_reset,
|
||||
|
||||
input device_clk,
|
||||
output device_reset,
|
||||
|
||||
input [11:0] up_raddr,
|
||||
output reg [31:0] up_rdata,
|
||||
|
||||
|
@ -76,25 +79,33 @@ module jesd204_up_common # (
|
|||
input [31:0] up_wdata,
|
||||
|
||||
input [EXTRA_CFG_WIDTH-1:0] up_extra_cfg,
|
||||
input [DEV_EXTRA_CFG_WIDTH-1:0] up_dev_extra_cfg,
|
||||
|
||||
input [NUM_IRQS-1:0] up_irq_trigger,
|
||||
output reg irq,
|
||||
|
||||
output up_cfg_is_writeable,
|
||||
|
||||
output reg [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output reg [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
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
|
||||
output reg [NUM_LANES-1:0] core_cfg_lanes_disable = {NUM_LANES{1'b0}},
|
||||
output reg [NUM_LINKS-1:0] core_cfg_links_disable = {NUM_LINKS{1'b0}},
|
||||
output reg [9:0] core_cfg_octets_per_multiframe = 'h00,
|
||||
output reg [7:0] core_cfg_octets_per_frame = 'h00,
|
||||
output reg core_cfg_disable_scrambler = 'h00,
|
||||
output reg core_cfg_disable_char_replacement = 'h00,
|
||||
output reg [EXTRA_CFG_WIDTH-1:0] core_extra_cfg = 'h00,
|
||||
|
||||
output reg [DEV_EXTRA_CFG_WIDTH-1:0] device_extra_cfg = 'h00,
|
||||
|
||||
output reg [9:0] device_cfg_octets_per_multiframe = 'h00,
|
||||
output reg [7:0] device_cfg_octets_per_frame = 'h00,
|
||||
output reg [7:0] device_cfg_beats_per_multiframe = 'h00
|
||||
);
|
||||
|
||||
reg [31:0] up_scratch = 32'h00000000;
|
||||
|
||||
reg [7:0] up_cfg_octets_per_frame = 'h00;
|
||||
reg [9:0] up_cfg_octets_per_multiframe = 'h00;
|
||||
reg [9:0] up_cfg_octets_per_multiframe = {DATA_PATH_WIDTH_LOG2{1'b1}};
|
||||
reg [7:0] up_cfg_beats_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;
|
||||
|
@ -108,6 +119,9 @@ assign up_reset = up_reset_vector[0];
|
|||
reg [4:0] core_reset_vector = 5'b11111;
|
||||
assign core_reset = core_reset_vector[0];
|
||||
|
||||
reg [4:0] device_reset_vector = 5'b11111;
|
||||
assign device_reset = device_reset_vector[0];
|
||||
|
||||
/* Transfer the reset signal back to the up domain, used to keep the
|
||||
* synchronizers in reset until the core is ready. This is done in order to
|
||||
* prevent bogus data to propagate to the register map. */
|
||||
|
@ -127,6 +141,9 @@ assign up_core_reset_ext = up_core_reset_ext_synchronizer_vector[0];
|
|||
wire core_cfg_transfer_en;
|
||||
assign core_cfg_transfer_en = core_reset_vector[2] ^ core_reset_vector[1];
|
||||
|
||||
wire device_cfg_transfer_en;
|
||||
assign device_cfg_transfer_en = device_reset_vector[2] ^ device_reset_vector[1];
|
||||
|
||||
reg up_reset_core = 1'b1;
|
||||
|
||||
assign up_cfg_is_writeable = up_reset_core;
|
||||
|
@ -149,6 +166,14 @@ always @(posedge core_clk or posedge core_reset_all) begin
|
|||
end
|
||||
end
|
||||
|
||||
always @(posedge device_clk or posedge core_reset_all) begin
|
||||
if (core_reset_all == 1'b1) begin
|
||||
device_reset_vector <= 5'b11111;
|
||||
end else begin
|
||||
device_reset_vector <= {1'b0,device_reset_vector[4:1]};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge up_clk or posedge core_reset) begin
|
||||
if (core_reset == 1'b1) begin
|
||||
up_reset_synchronizer_vector <= 2'b11;
|
||||
|
@ -177,6 +202,15 @@ always @(posedge core_clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
if (device_cfg_transfer_en == 1'b1) begin
|
||||
device_cfg_octets_per_multiframe <= up_cfg_octets_per_multiframe;
|
||||
device_cfg_octets_per_frame <= up_cfg_octets_per_frame;
|
||||
device_cfg_beats_per_multiframe <= up_cfg_beats_per_multiframe;
|
||||
device_extra_cfg <= up_dev_extra_cfg;
|
||||
end
|
||||
end
|
||||
|
||||
/* Interupt handling */
|
||||
reg [NUM_IRQS-1:0] up_irq_enable = {NUM_IRQS{1'b0}};
|
||||
reg [NUM_IRQS-1:0] up_irq_source = 'h00;
|
||||
|
@ -251,6 +285,7 @@ end
|
|||
endgenerate
|
||||
|
||||
wire [20:0] clk_mon_count;
|
||||
wire [20:0] device_clk_mon_count;
|
||||
|
||||
always @(*) begin
|
||||
case (up_raddr)
|
||||
|
@ -277,7 +312,8 @@ always @(*) begin
|
|||
12'h030: up_rdata = up_reset_core;
|
||||
12'h031: up_rdata = {up_core_reset_ext, up_reset_synchronizer}; /* core ready */
|
||||
12'h032: up_rdata = {11'h00, clk_mon_count}; /* Make it 16.16 */
|
||||
/* 0x32-0x34 reserver for future use */
|
||||
12'h033: up_rdata = {11'h00, device_clk_mon_count}; /* Make it 16.16 */
|
||||
/* 0x34-0x34 reserver for future use */
|
||||
|
||||
12'h080: up_rdata = up_cfg_lanes_disable;
|
||||
/* 0x82-0x83 reserved for future lane disable bits (max 128 lanes) */
|
||||
|
@ -293,7 +329,8 @@ always @(*) begin
|
|||
/* 00 */ up_cfg_disable_scrambler /* Disable scrambler */
|
||||
};
|
||||
12'h086: up_rdata = up_cfg_links_disable;
|
||||
/* 0x87-0x8f reserved for future use */
|
||||
12'h087: up_rdata = up_cfg_beats_per_multiframe;
|
||||
/* 0x88-0x8f reserved for future use */
|
||||
|
||||
/* 0x90-0x9f reserved for core specific configuration options */
|
||||
|
||||
|
@ -325,9 +362,10 @@ always @(posedge up_clk) begin
|
|||
up_reset_core <= 1'b1;
|
||||
|
||||
up_cfg_octets_per_frame <= 'h00;
|
||||
up_cfg_octets_per_multiframe <= 'h00;
|
||||
up_cfg_octets_per_multiframe <= {DATA_PATH_WIDTH_LOG2{1'b1}};
|
||||
up_cfg_lanes_disable <= {NUM_LANES{1'b0}};
|
||||
up_cfg_links_disable <= {NUM_LINKS{1'b0}};
|
||||
up_cfg_beats_per_multiframe <= 'h00;
|
||||
|
||||
up_cfg_disable_char_replacement <= 1'b0;
|
||||
up_cfg_disable_scrambler <= 1'b0;
|
||||
|
@ -356,7 +394,8 @@ always @(posedge up_clk) begin
|
|||
end
|
||||
12'h084: begin
|
||||
up_cfg_octets_per_frame <= up_wdata[23:16];
|
||||
up_cfg_octets_per_multiframe <= up_wdata[9:0];
|
||||
up_cfg_octets_per_multiframe <= {up_wdata[9:DATA_PATH_WIDTH_LOG2],
|
||||
{DATA_PATH_WIDTH_LOG2{1'b1}}};
|
||||
end
|
||||
12'h085: begin
|
||||
up_cfg_disable_char_replacement <= up_wdata[1];
|
||||
|
@ -365,6 +404,9 @@ always @(posedge up_clk) begin
|
|||
12'h086: begin
|
||||
up_cfg_links_disable <= up_wdata[NUM_LINKS-1:0];
|
||||
end
|
||||
12'h087: begin
|
||||
up_cfg_beats_per_multiframe <= up_wdata[7:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -380,4 +422,14 @@ up_clock_mon #(
|
|||
.d_clk(core_clk)
|
||||
);
|
||||
|
||||
up_clock_mon #(
|
||||
.TOTAL_WIDTH(21)
|
||||
) i_dev_clock_mon (
|
||||
.up_rstn(~up_reset),
|
||||
.up_clk(up_clk),
|
||||
.up_d_count(device_clk_mon_count),
|
||||
.d_rst(1'b0),
|
||||
.d_clk(device_clk)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -52,6 +52,8 @@ module jesd204_up_sysref #(
|
|||
|
||||
input core_clk,
|
||||
|
||||
input device_clk,
|
||||
|
||||
input [11:0] up_raddr,
|
||||
output reg [31:0] up_rdata,
|
||||
|
||||
|
@ -65,8 +67,8 @@ module jesd204_up_sysref #(
|
|||
output reg [7:0] up_cfg_lmfc_offset,
|
||||
output reg up_cfg_sysref_disable,
|
||||
|
||||
input core_event_sysref_alignment_error,
|
||||
input core_event_sysref_edge
|
||||
input device_event_sysref_alignment_error,
|
||||
input device_event_sysref_edge
|
||||
);
|
||||
|
||||
reg [1:0] up_sysref_status;
|
||||
|
@ -76,10 +78,10 @@ wire [1:0] up_sysref_event;
|
|||
sync_event #(
|
||||
.NUM_OF_EVENTS(2)
|
||||
) i_cdc_sysref_event (
|
||||
.in_clk(core_clk),
|
||||
.in_clk(device_clk),
|
||||
.in_event({
|
||||
core_event_sysref_alignment_error,
|
||||
core_event_sysref_edge
|
||||
device_event_sysref_alignment_error,
|
||||
device_event_sysref_edge
|
||||
}),
|
||||
.out_clk(up_clk),
|
||||
.out_event(up_sysref_event)
|
||||
|
@ -127,8 +129,8 @@ always @(posedge up_clk) begin
|
|||
up_cfg_sysref_disable <= up_wdata[0];
|
||||
end
|
||||
12'h041: begin
|
||||
/* Aligned to data path width */
|
||||
up_cfg_lmfc_offset <= up_wdata[9:DATA_PATH_WIDTH_LOG2];
|
||||
/* Must be aligned to data path width */
|
||||
up_cfg_lmfc_offset <= up_wdata;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -81,25 +81,32 @@ module axi_jesd204_rx #(
|
|||
input core_reset_ext,
|
||||
output core_reset,
|
||||
|
||||
input device_clk,
|
||||
output device_reset,
|
||||
|
||||
output [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
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,
|
||||
output [7:0] core_cfg_lmfc_offset,
|
||||
output core_cfg_sysref_oneshot,
|
||||
output core_cfg_sysref_disable,
|
||||
output core_cfg_buffer_early_release,
|
||||
output [7:0] core_cfg_buffer_delay,
|
||||
output [7:0] core_cfg_frame_align_err_threshold,
|
||||
|
||||
output [9:0] device_cfg_octets_per_multiframe,
|
||||
output [7:0] device_cfg_octets_per_frame,
|
||||
output [7:0] device_cfg_beats_per_multiframe,
|
||||
output [7:0] device_cfg_lmfc_offset,
|
||||
output device_cfg_sysref_oneshot,
|
||||
output device_cfg_sysref_disable,
|
||||
output device_cfg_buffer_early_release,
|
||||
output [7:0] device_cfg_buffer_delay,
|
||||
|
||||
input [NUM_LANES-1:0] core_ilas_config_valid,
|
||||
input [2*NUM_LANES-1:0] core_ilas_config_addr,
|
||||
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] core_ilas_config_data,
|
||||
|
||||
input core_event_sysref_alignment_error,
|
||||
input core_event_sysref_edge,
|
||||
input device_event_sysref_alignment_error,
|
||||
input device_event_sysref_edge,
|
||||
input core_event_frame_alignment_error,
|
||||
input core_event_unexpected_lane_state_error,
|
||||
|
||||
|
@ -135,7 +142,7 @@ wire [31:0] up_rdata_common;
|
|||
wire [31:0] up_rdata_sysref;
|
||||
wire [31:0] up_rdata_rx;
|
||||
|
||||
wire [4:0] up_irq_trigger = 5'b00000;
|
||||
wire [4:0] up_irq_trigger;
|
||||
|
||||
wire up_cfg_is_writeable;
|
||||
wire up_cfg_sysref_oneshot;
|
||||
|
@ -206,7 +213,8 @@ jesd204_up_common #(
|
|||
.NUM_LINKS(NUM_LINKS),
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2),
|
||||
.NUM_IRQS(5),
|
||||
.EXTRA_CFG_WIDTH(27),
|
||||
.EXTRA_CFG_WIDTH(8),
|
||||
.DEV_EXTRA_CFG_WIDTH(19),
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.ENABLE_LINK_STATS(ENABLE_LINK_STATS)
|
||||
) i_up_common (
|
||||
|
@ -220,6 +228,9 @@ jesd204_up_common #(
|
|||
.core_reset_ext(core_reset_ext),
|
||||
.core_reset(core_reset),
|
||||
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_common),
|
||||
.up_wreq(up_wreq),
|
||||
|
@ -239,20 +250,29 @@ jesd204_up_common #(
|
|||
.core_cfg_disable_char_replacement(core_cfg_disable_char_replacement),
|
||||
|
||||
.up_extra_cfg({
|
||||
/* 19-26 */ up_cfg_frame_align_err_threshold,
|
||||
/* 00-07 */ up_cfg_frame_align_err_threshold
|
||||
}),
|
||||
.core_extra_cfg({
|
||||
/* 00-07 */ core_cfg_frame_align_err_threshold
|
||||
}),
|
||||
|
||||
.device_cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
||||
.device_cfg_octets_per_frame(device_cfg_octets_per_frame),
|
||||
.device_cfg_beats_per_multiframe(device_cfg_beats_per_multiframe),
|
||||
|
||||
.up_dev_extra_cfg({
|
||||
/* 18 */ up_cfg_sysref_disable,
|
||||
/* 17 */ up_cfg_sysref_oneshot,
|
||||
/* 16 */ up_cfg_buffer_early_release,
|
||||
/* 08-15 */ up_cfg_buffer_delay,
|
||||
/* 15-08 */ up_cfg_buffer_delay,
|
||||
/* 00-07 */ up_cfg_lmfc_offset
|
||||
}),
|
||||
.core_extra_cfg({
|
||||
/* 19-26 */ core_cfg_frame_align_err_threshold,
|
||||
/* 18 */ core_cfg_sysref_disable,
|
||||
/* 17 */ core_cfg_sysref_oneshot,
|
||||
/* 16 */ core_cfg_buffer_early_release,
|
||||
/* 08-15 */ core_cfg_buffer_delay,
|
||||
/* 00-07 */ core_cfg_lmfc_offset
|
||||
.device_extra_cfg({
|
||||
/* 18 */ device_cfg_sysref_disable,
|
||||
/* 17 */ device_cfg_sysref_oneshot,
|
||||
/* 16 */ device_cfg_buffer_early_release,
|
||||
/* 15-08 */ device_cfg_buffer_delay,
|
||||
/* 00-07 */ device_cfg_lmfc_offset
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -263,8 +283,9 @@ jesd204_up_sysref #(
|
|||
.up_reset(up_reset),
|
||||
|
||||
.core_clk(core_clk),
|
||||
.core_event_sysref_edge(core_event_sysref_edge),
|
||||
.core_event_sysref_alignment_error(core_event_sysref_alignment_error),
|
||||
.device_clk(device_clk),
|
||||
.device_event_sysref_edge(device_event_sysref_edge),
|
||||
.device_event_sysref_alignment_error(device_event_sysref_alignment_error),
|
||||
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_sysref),
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
set axi_clk [get_clocks -of_objects [get_ports s_axi_aclk]]
|
||||
set core_clk [get_clocks -of_objects [get_ports core_clk]]
|
||||
set device_clk [get_clocks -of_objects [get_ports device_clk]]
|
||||
|
||||
set_property ASYNC_REG TRUE \
|
||||
[get_cells -hier {*cdc_sync_stage1_reg*}] \
|
||||
|
@ -130,6 +131,10 @@ set_false_path \
|
|||
-from [get_pins {i_up_common/up_reset_core_reg/C}] \
|
||||
-to [get_pins {i_up_common/core_reset_vector_reg[*]/PRE}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins {i_up_common/up_reset_core_reg/C}] \
|
||||
-to [get_pins {i_up_common/device_reset_vector_reg[*]/PRE}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins {i_up_common/core_reset_vector_reg[0]/C}] \
|
||||
-to [get_pins {i_up_common/up_reset_synchronizer_vector_reg[*]/PRE}]
|
||||
|
@ -142,12 +147,22 @@ set_max_delay -datapath_only \
|
|||
-to [get_pins {i_up_common/core_cfg_*_reg*/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_common/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/device_cfg_*_reg*/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_rx/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
-to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
|
|
@ -79,16 +79,19 @@ adi_add_bus "rx_cfg" "master" \
|
|||
{ "core_cfg_links_disable" "links_disable" } \
|
||||
{ "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" } \
|
||||
{ "core_cfg_sysref_disable" "sysref_disable" } \
|
||||
{ "core_ctrl_err_statistics_reset" "err_statistics_reset" } \
|
||||
{ "core_ctrl_err_statistics_mask" "err_statistics_mask" } \
|
||||
{ "core_cfg_buffer_early_release" "buffer_early_release" } \
|
||||
{ "core_cfg_buffer_delay" "buffer_delay" } \
|
||||
{ "core_cfg_disable_char_replacement" "disable_char_replacement" } \
|
||||
{ "core_cfg_disable_scrambler" "disable_scrambler" } \
|
||||
{ "core_cfg_frame_align_err_threshold" "frame_align_err_threshold" } \
|
||||
{ "device_cfg_octets_per_multiframe" "device_octets_per_multiframe" } \
|
||||
{ "device_cfg_octets_per_frame" "device_octets_per_frame" } \
|
||||
{ "device_cfg_beats_per_multiframe" "device_beats_per_multiframe" } \
|
||||
{ "device_cfg_lmfc_offset" "device_lmfc_offset" } \
|
||||
{ "device_cfg_sysref_oneshot" "device_sysref_oneshot" } \
|
||||
{ "device_cfg_sysref_disable" "device_sysref_disable" } \
|
||||
{ "device_cfg_buffer_early_release" "device_buffer_early_release" } \
|
||||
{ "device_cfg_buffer_delay" "device_buffer_delay" } \
|
||||
{ "core_ctrl_err_statistics_reset" "err_statistics_reset" } \
|
||||
{ "core_ctrl_err_statistics_mask" "err_statistics_mask" } \
|
||||
}
|
||||
|
||||
adi_add_bus "rx_ilas_config" "slave" \
|
||||
|
@ -104,8 +107,8 @@ adi_add_bus "rx_event" "slave" \
|
|||
"analog.com:interface:jesd204_rx_event_rtl:1.0" \
|
||||
"analog.com:interface:jesd204_rx_event:1.0" \
|
||||
{ \
|
||||
{ "core_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "core_event_sysref_edge" "sysref_edge" } \
|
||||
{ "device_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "device_event_sysref_edge" "sysref_edge" } \
|
||||
{ "core_event_frame_alignment_error" "frame_alignment_error" } \
|
||||
{ "core_event_unexpected_lane_state_error" "unexpected_lane_state_error" } \
|
||||
}
|
||||
|
|
|
@ -81,13 +81,13 @@ module axi_jesd204_tx #(
|
|||
input core_reset_ext,
|
||||
output core_reset,
|
||||
|
||||
input device_clk,
|
||||
output device_reset,
|
||||
|
||||
output [NUM_LANES-1:0] core_cfg_lanes_disable,
|
||||
output [NUM_LINKS-1:0] core_cfg_links_disable,
|
||||
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,
|
||||
output core_cfg_sysref_disable,
|
||||
output core_cfg_continuous_cgs,
|
||||
output core_cfg_continuous_ilas,
|
||||
output core_cfg_skip_ilas,
|
||||
|
@ -95,12 +95,19 @@ module axi_jesd204_tx #(
|
|||
output core_cfg_disable_char_replacement,
|
||||
output core_cfg_disable_scrambler,
|
||||
|
||||
output [7:0] device_cfg_octets_per_multiframe,
|
||||
output [7:0] device_cfg_octets_per_frame,
|
||||
output [7:0] device_cfg_beats_per_multiframe,
|
||||
output [7:0] device_cfg_lmfc_offset,
|
||||
output device_cfg_sysref_oneshot,
|
||||
output device_cfg_sysref_disable,
|
||||
|
||||
input core_ilas_config_rd,
|
||||
input [1:0] core_ilas_config_addr,
|
||||
output [DATA_PATH_WIDTH*8*NUM_LANES-1:0] core_ilas_config_data,
|
||||
|
||||
input core_event_sysref_alignment_error,
|
||||
input core_event_sysref_edge,
|
||||
input device_event_sysref_alignment_error,
|
||||
input device_event_sysref_edge,
|
||||
|
||||
output core_ctrl_manual_sync_request,
|
||||
|
||||
|
@ -181,8 +188,9 @@ jesd204_up_common #(
|
|||
.NUM_LINKS(NUM_LINKS),
|
||||
.DATA_PATH_WIDTH_LOG2(DATA_PATH_WIDTH_LOG2),
|
||||
.NUM_IRQS(5),
|
||||
.EXTRA_CFG_WIDTH(21),
|
||||
.MAX_OCTETS_PER_FRAME(8),
|
||||
.EXTRA_CFG_WIDTH(11),
|
||||
.DEV_EXTRA_CFG_WIDTH(10),
|
||||
.MAX_OCTETS_PER_FRAME(10),
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.ENABLE_LINK_STATS(ENABLE_LINK_STATS)
|
||||
) i_up_common (
|
||||
|
@ -197,6 +205,9 @@ jesd204_up_common #(
|
|||
.core_reset_ext(core_reset_ext),
|
||||
.core_reset(core_reset),
|
||||
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_common),
|
||||
|
||||
|
@ -217,22 +228,31 @@ jesd204_up_common #(
|
|||
.core_cfg_disable_char_replacement(core_cfg_disable_char_replacement),
|
||||
|
||||
.up_extra_cfg({
|
||||
/* 20 */ up_cfg_sysref_disable,
|
||||
/* 19 */ up_cfg_sysref_oneshot,
|
||||
/* 18 */ up_cfg_continuous_cgs,
|
||||
/* 17 */ up_cfg_continuous_ilas,
|
||||
/* 16 */ up_cfg_skip_ilas,
|
||||
/* 08-15 */ up_cfg_lmfc_offset,
|
||||
/* 10 */ up_cfg_continuous_cgs,
|
||||
/* 09 */ up_cfg_continuous_ilas,
|
||||
/* 08 */ up_cfg_skip_ilas,
|
||||
/* 00-07 */ up_cfg_mframes_per_ilas
|
||||
}),
|
||||
.core_extra_cfg({
|
||||
/* 20 */ core_cfg_sysref_disable,
|
||||
/* 19 */ core_cfg_sysref_oneshot,
|
||||
/* 18 */ core_cfg_continuous_cgs,
|
||||
/* 17 */ core_cfg_continuous_ilas,
|
||||
/* 16 */ core_cfg_skip_ilas,
|
||||
/* 08-15 */ core_cfg_lmfc_offset,
|
||||
/* 10 */ core_cfg_continuous_cgs,
|
||||
/* 09 */ core_cfg_continuous_ilas,
|
||||
/* 08 */ core_cfg_skip_ilas,
|
||||
/* 00-07 */ core_cfg_mframes_per_ilas
|
||||
}),
|
||||
|
||||
.device_cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
||||
.device_cfg_octets_per_frame(device_cfg_octets_per_frame),
|
||||
.device_cfg_beats_per_multiframe(device_cfg_beats_per_multiframe),
|
||||
|
||||
.up_dev_extra_cfg({
|
||||
/* 09 */ up_cfg_sysref_disable,
|
||||
/* 08 */ up_cfg_sysref_oneshot,
|
||||
/* 00-07 */ up_cfg_lmfc_offset
|
||||
}),
|
||||
.device_extra_cfg({
|
||||
/* 09 */ device_cfg_sysref_disable,
|
||||
/* 08 */ device_cfg_sysref_oneshot,
|
||||
/* 00-07 */ device_cfg_lmfc_offset
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -243,8 +263,9 @@ jesd204_up_sysref #(
|
|||
.up_reset(up_reset),
|
||||
|
||||
.core_clk(core_clk),
|
||||
.core_event_sysref_alignment_error(core_event_sysref_alignment_error),
|
||||
.core_event_sysref_edge(core_event_sysref_edge),
|
||||
.device_clk(device_clk),
|
||||
.device_event_sysref_alignment_error(device_event_sysref_alignment_error),
|
||||
.device_event_sysref_edge(device_event_sysref_edge),
|
||||
|
||||
.up_cfg_lmfc_offset(up_cfg_lmfc_offset),
|
||||
.up_cfg_sysref_oneshot(up_cfg_sysref_oneshot),
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
set axi_clk [get_clocks -of_objects [get_ports s_axi_aclk]]
|
||||
set core_clk [get_clocks -of_objects [get_ports core_clk]]
|
||||
set device_clk [get_clocks -of_objects [get_ports device_clk]]
|
||||
|
||||
set_property ASYNC_REG TRUE \
|
||||
[get_cells -hier {*cdc_sync_stage1_reg*}] \
|
||||
|
@ -90,6 +91,10 @@ set_false_path \
|
|||
-from [get_pins {i_up_common/up_reset_core_reg/C}] \
|
||||
-to [get_pins {i_up_common/core_reset_vector_reg[*]/PRE}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins {i_up_common/up_reset_core_reg/C}] \
|
||||
-to [get_pins {i_up_common/device_reset_vector_reg[*]/PRE}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins {i_up_common/core_reset_vector_reg[0]/C}] \
|
||||
-to [get_pins {i_up_common/up_reset_synchronizer_vector_reg[*]/PRE}]
|
||||
|
@ -102,6 +107,11 @@ set_max_delay -datapath_only \
|
|||
-to [get_pins {i_up_common/core_cfg_*_reg*/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_common/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/device_cfg_*_reg*/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_tx/up_cfg_ilas_data_*_reg*/C}] \
|
||||
-to [get_cells {i_up_tx/*core_ilas_config_data_reg*}] \
|
||||
|
@ -112,10 +122,15 @@ set_max_delay -datapath_only \
|
|||
-to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_tx/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
||||
set_max_delay -datapath_only \
|
||||
-from [get_pins {i_up_sysref/up_cfg_*_reg*/C}] \
|
||||
-to [get_pins {i_up_common/core_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $core_clk]
|
||||
-to [get_pins {i_up_common/device_extra_cfg_reg[*]/D}] \
|
||||
[get_property -min PERIOD $device_clk]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins {i_up_tx/i_cdc_manual_sync_request/out_toggle_d1_reg/C}] \
|
||||
|
|
|
@ -77,15 +77,18 @@ adi_add_bus "tx_cfg" "master" \
|
|||
{ "core_cfg_links_disable" "links_disable" } \
|
||||
{ "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" } \
|
||||
{ "core_cfg_sysref_disable" "sysref_disable" } \
|
||||
{ "core_cfg_continuous_cgs" "continuous_cgs" } \
|
||||
{ "core_cfg_continuous_ilas" "continuous_ilas" } \
|
||||
{ "core_cfg_skip_ilas" "skip_ilas" } \
|
||||
{ "core_cfg_mframes_per_ilas" "mframes_per_ilas" } \
|
||||
{ "core_cfg_disable_char_replacement" "disable_char_replacement" } \
|
||||
{ "core_cfg_disable_scrambler" "disable_scrambler" } \
|
||||
{ "device_cfg_octets_per_multiframe" "device_octets_per_multiframe" } \
|
||||
{ "device_cfg_octets_per_frame" "device_octets_per_frame" } \
|
||||
{ "device_cfg_beats_per_multiframe" "device_beats_per_multiframe" } \
|
||||
{ "device_cfg_lmfc_offset" "device_lmfc_offset" } \
|
||||
{ "device_cfg_sysref_oneshot" "device_sysref_oneshot" } \
|
||||
{ "device_cfg_sysref_disable" "device_sysref_disable" } \
|
||||
}
|
||||
|
||||
adi_add_bus "tx_ilas_config" "slave" \
|
||||
|
@ -101,8 +104,8 @@ adi_add_bus "tx_event" "slave" \
|
|||
"analog.com:interface:jesd204_tx_event_rtl:1.0" \
|
||||
"analog.com:interface:jesd204_tx_event:1.0" \
|
||||
{ \
|
||||
{ "core_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "core_event_sysref_edge" "sysref_edge" } \
|
||||
{ "device_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "device_event_sysref_edge" "sysref_edge" } \
|
||||
}
|
||||
|
||||
adi_add_bus "tx_status" "slave" \
|
||||
|
|
|
@ -52,13 +52,18 @@ adi_if_ports output -1 lanes_disable
|
|||
adi_if_ports output -1 links_disable
|
||||
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
|
||||
adi_if_ports output 1 continuous_ilas
|
||||
adi_if_ports output 1 skip_ilas
|
||||
adi_if_ports output 8 mframes_per_ilas
|
||||
adi_if_ports output 1 disable_char_replacement
|
||||
adi_if_ports output 1 disable_scrambler
|
||||
adi_if_ports output 10 device_octets_per_multiframe
|
||||
adi_if_ports output 8 device_octets_per_frame
|
||||
adi_if_ports output 8 device_beats_per_multiframe
|
||||
adi_if_ports output 8 device_lmfc_offset
|
||||
adi_if_ports output 1 device_sysref_oneshot
|
||||
adi_if_ports output 1 device_sysref_disable
|
||||
|
||||
adi_if_define "jesd204_tx_ilas_config"
|
||||
adi_if_ports output 1 rd
|
||||
|
@ -83,12 +88,17 @@ adi_if_ports output -1 lanes_disable
|
|||
adi_if_ports output -1 links_disable
|
||||
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
|
||||
adi_if_ports output 1 buffer_delay
|
||||
adi_if_ports output 1 disable_char_replacement
|
||||
adi_if_ports output 1 disable_scrambler
|
||||
adi_if_ports output 8 frame_align_err_threshold
|
||||
adi_if_ports output 10 device_octets_per_multiframe
|
||||
adi_if_ports output 8 device_octets_per_frame
|
||||
adi_if_ports output 8 device_beats_per_multiframe
|
||||
adi_if_ports output 8 device_lmfc_offset
|
||||
adi_if_ports output 1 device_sysref_oneshot
|
||||
adi_if_ports output 1 device_sysref_disable
|
||||
adi_if_ports output 1 device_buffer_early_release
|
||||
adi_if_ports output 1 device_buffer_delay
|
||||
adi_if_ports output 1 err_statistics_reset
|
||||
adi_if_ports output 7 err_statistics_mask
|
||||
|
||||
|
|
|
@ -43,9 +43,13 @@
|
|||
//
|
||||
|
||||
// Limitations:
|
||||
// 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
|
||||
// for 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
|
||||
// for DATA_PATH_WIDTH = 6
|
||||
// F=3,6
|
||||
// for DATA_PATH_WIDTH = 12
|
||||
// F=3,6,12
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
|
@ -55,6 +59,7 @@ module jesd204_frame_mark #(
|
|||
input clk,
|
||||
input reset,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
|
||||
output reg [DATA_PATH_WIDTH-1:0] sof,
|
||||
|
@ -75,7 +80,6 @@ localparam CW = MAX_OCTETS_PER_FRAME > 128 ? 8 :
|
|||
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;
|
||||
|
@ -114,6 +118,21 @@ initial begin
|
|||
eof_f_6[1] = {4'b0010};
|
||||
eof_f_6[2] = {4'b1000};
|
||||
end
|
||||
end else if(DATA_PATH_WIDTH == 6) begin : gen_dp_6
|
||||
initial begin
|
||||
sof_f_3[0] = {6'b001001};
|
||||
sof_f_3[1] = {6'b001001};
|
||||
sof_f_3[2] = {6'b001001};
|
||||
eof_f_3[0] = {6'b100100};
|
||||
eof_f_3[1] = {6'b100100};
|
||||
eof_f_3[2] = {6'b100100};
|
||||
sof_f_6[0] = {6'b000001};
|
||||
sof_f_6[1] = {6'b000001};
|
||||
sof_f_6[2] = {6'b000001};
|
||||
eof_f_6[0] = {6'b100000};
|
||||
eof_f_6[1] = {6'b100000};
|
||||
eof_f_6[2] = {6'b100000};
|
||||
end
|
||||
end else if(DATA_PATH_WIDTH == 8) begin : gen_dp_8
|
||||
initial begin
|
||||
sof_f_3[0] = {8'b01001001};
|
||||
|
@ -232,7 +251,7 @@ end
|
|||
assign cur_somf = beat_cnt_mf == 0;
|
||||
assign cur_eomf = beat_cnt_mf == cur_beats_per_multiframe;
|
||||
|
||||
if(DATA_PATH_WIDTH == 4) begin : gen_mf_dp_4
|
||||
if(DATA_PATH_WIDTH == 4 || DATA_PATH_WIDTH == 6) begin : gen_mf_dp_4_6
|
||||
always @(*) begin
|
||||
cur_beats_per_multiframe = cfg_beats_per_multiframe;
|
||||
somf = {{DATA_PATH_WIDTH-1{1'b0}}, cur_somf};
|
||||
|
|
|
@ -54,6 +54,7 @@ module jesd204_lmfc #(
|
|||
input sysref,
|
||||
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_beats_per_multiframe,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_oneshot,
|
||||
input cfg_sysref_disable,
|
||||
|
@ -75,7 +76,7 @@ module jesd204_lmfc #(
|
|||
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];
|
||||
//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;
|
||||
|
|
|
@ -30,6 +30,7 @@ XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_ilas_config.xml
|
|||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_ilas_config_rtl.xml
|
||||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_status.xml
|
||||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_rx_status_rtl.xml
|
||||
XILINX_DEPS += bd/bd.tcl
|
||||
|
||||
XILINX_LIB_DEPS += jesd204/jesd204_common
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
proc init {cellpath otherInfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
bd::mark_propagate_override $ip \
|
||||
"ASYNC_CLK"
|
||||
|
||||
}
|
||||
|
||||
proc detect_async_clk { cellpath ip param_name clk_a clk_b } {
|
||||
set param_src [get_property "CONFIG.$param_name.VALUE_SRC" $ip]
|
||||
if {[string equal $param_src "USER"]} {
|
||||
return;
|
||||
}
|
||||
|
||||
set clk_domain_a [get_property CONFIG.CLK_DOMAIN $clk_a]
|
||||
set clk_domain_b [get_property CONFIG.CLK_DOMAIN $clk_b]
|
||||
set clk_freq_a [get_property CONFIG.FREQ_HZ $clk_a]
|
||||
set clk_freq_b [get_property CONFIG.FREQ_HZ $clk_b]
|
||||
set clk_phase_a [get_property CONFIG.PHASE $clk_a]
|
||||
set clk_phase_b [get_property CONFIG.PHASE $clk_b]
|
||||
|
||||
# Only mark it as sync if we can make sure that it is sync, if the
|
||||
# relationship of the clocks is unknown mark it as async
|
||||
if {$clk_domain_a != {} && $clk_domain_b != {} && \
|
||||
$clk_domain_a == $clk_domain_b && $clk_freq_a == $clk_freq_b && \
|
||||
$clk_phase_a == $clk_phase_b} {
|
||||
set clk_async 0
|
||||
} else {
|
||||
set clk_async 1
|
||||
}
|
||||
|
||||
set_property "CONFIG.$param_name" $clk_async $ip
|
||||
|
||||
}
|
||||
|
||||
proc propagate {cellpath otherinfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
set link_clk [get_bd_pins "$ip/clk"]
|
||||
set device_clk [get_bd_pins "$ip/device_clk"]
|
||||
|
||||
detect_async_clk $cellpath $ip "ASYNC_CLK" $link_clk $device_clk
|
||||
}
|
||||
|
|
@ -45,15 +45,20 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module elastic_buffer #(
|
||||
parameter WIDTH = 32,
|
||||
parameter SIZE = 256
|
||||
parameter IWIDTH = 32,
|
||||
parameter OWIDTH = 48,
|
||||
parameter SIZE = 256,
|
||||
parameter ASYNC_CLK = 0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [WIDTH-1:0] wr_data,
|
||||
input device_clk,
|
||||
input device_reset,
|
||||
|
||||
output reg [WIDTH-1:0] rd_data,
|
||||
input [IWIDTH-1:0] wr_data,
|
||||
|
||||
output reg [OWIDTH-1:0] rd_data,
|
||||
|
||||
input ready_n,
|
||||
input do_release_n
|
||||
|
@ -67,20 +72,45 @@ localparam ADDR_WIDTH = SIZE > 128 ? 7 :
|
|||
SIZE > 4 ? 2 :
|
||||
SIZE > 2 ? 1 : 0;
|
||||
|
||||
localparam WIDTH = OWIDTH >= IWIDTH ? OWIDTH : IWIDTH;
|
||||
|
||||
reg [ADDR_WIDTH:0] wr_addr = 'h00;
|
||||
reg [ADDR_WIDTH:0] rd_addr = 'h00;
|
||||
reg [WIDTH-1:0] mem[0:SIZE - 1];
|
||||
(* ram_style = "distributed" *) reg [WIDTH-1:0] mem[0:SIZE - 1];
|
||||
|
||||
wire mem_wr;
|
||||
wire [WIDTH-1:0] mem_wr_data;
|
||||
|
||||
generate if ((OWIDTH > IWIDTH) && ASYNC_CLK) begin
|
||||
ad_pack #(
|
||||
.I_W(IWIDTH/8),
|
||||
.O_W(OWIDTH/8),
|
||||
.UNIT_W(8)
|
||||
) i_ad_pack (
|
||||
.clk(clk),
|
||||
.reset(ready_n),
|
||||
.idata(wr_data),
|
||||
.ivalid(1'b1),
|
||||
|
||||
.odata(mem_wr_data),
|
||||
.ovalid(mem_wr)
|
||||
);
|
||||
end else begin
|
||||
assign mem_wr = 1'b1;
|
||||
assign mem_wr_data = wr_data;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ready_n == 1'b1) begin
|
||||
wr_addr <= 'h00;
|
||||
end else begin
|
||||
mem[wr_addr] <= wr_data;
|
||||
end else if (mem_wr) begin
|
||||
mem[wr_addr] <= mem_wr_data;
|
||||
wr_addr <= wr_addr + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
always @(posedge device_clk) begin
|
||||
if (do_release_n == 1'b1) begin
|
||||
rd_addr <= 'h00;
|
||||
end else begin
|
||||
|
|
|
@ -53,11 +53,16 @@ module jesd204_rx #(
|
|||
parameter DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4,
|
||||
parameter ENABLE_FRAME_ALIGN_CHECK = 1,
|
||||
parameter ENABLE_FRAME_ALIGN_ERR_RESET = 0,
|
||||
parameter ENABLE_CHAR_REPLACE = 0
|
||||
parameter ENABLE_CHAR_REPLACE = 0,
|
||||
parameter ASYNC_CLK = 1,
|
||||
parameter TPL_DATA_PATH_WIDTH = LINK_MODE == 2 ? 8 : 4
|
||||
) (
|
||||
input clk,
|
||||
input clk, // Link clock, lane rate / 40 or lane rate / 20 or lane rate / 66
|
||||
input reset,
|
||||
|
||||
input device_clk, // Integer multiple of frame clock
|
||||
input device_reset,
|
||||
|
||||
input [DATA_PATH_WIDTH*8*NUM_LANES-1:0] phy_data,
|
||||
input [2*NUM_LANES-1:0] phy_header,
|
||||
input [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_charisk,
|
||||
|
@ -69,8 +74,8 @@ module jesd204_rx #(
|
|||
output lmfc_edge,
|
||||
output lmfc_clk,
|
||||
|
||||
output event_sysref_alignment_error,
|
||||
output event_sysref_edge,
|
||||
output device_event_sysref_alignment_error,
|
||||
output device_event_sysref_edge,
|
||||
output event_frame_alignment_error,
|
||||
output event_unexpected_lane_state_error,
|
||||
|
||||
|
@ -78,30 +83,33 @@ module jesd204_rx #(
|
|||
|
||||
output phy_en_char_align,
|
||||
|
||||
output [DATA_PATH_WIDTH*8*NUM_LANES-1:0] rx_data,
|
||||
output [TPL_DATA_PATH_WIDTH*8*NUM_LANES-1:0] rx_data,
|
||||
output rx_valid,
|
||||
output [DATA_PATH_WIDTH-1:0] rx_eof,
|
||||
output [DATA_PATH_WIDTH-1:0] rx_sof,
|
||||
output [DATA_PATH_WIDTH-1:0] rx_eomf,
|
||||
output [DATA_PATH_WIDTH-1:0] rx_somf,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] rx_eof,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] rx_sof,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] rx_eomf,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] rx_somf,
|
||||
|
||||
input [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
input [NUM_LINKS-1:0] cfg_links_disable,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_disable,
|
||||
input cfg_sysref_oneshot,
|
||||
input cfg_buffer_early_release,
|
||||
input [7:0] cfg_buffer_delay,
|
||||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler,
|
||||
input cfg_disable_char_replacement,
|
||||
input [7:0] cfg_frame_align_err_threshold,
|
||||
|
||||
input [9:0] device_cfg_octets_per_multiframe,
|
||||
input [7:0] device_cfg_octets_per_frame,
|
||||
input [7:0] device_cfg_beats_per_multiframe,
|
||||
input [7:0] device_cfg_lmfc_offset,
|
||||
input device_cfg_sysref_oneshot,
|
||||
input device_cfg_sysref_disable,
|
||||
input device_cfg_buffer_early_release,
|
||||
input [7:0] device_cfg_buffer_delay,
|
||||
|
||||
input ctrl_err_statistics_reset,
|
||||
input [6:0] ctrl_err_statistics_mask,
|
||||
|
||||
input [7:0] cfg_frame_align_err_threshold,
|
||||
|
||||
output [32*NUM_LANES-1:0] status_err_statistics_cnt,
|
||||
|
||||
output [NUM_LANES-1:0] ilas_config_valid,
|
||||
|
@ -146,10 +154,12 @@ localparam LMFC_COUNTER_WIDTH = MAX_BEATS_PER_MULTIFRAME > 256 ? 9 :
|
|||
|
||||
/* Helper for common expressions */
|
||||
localparam DW = 8*DATA_PATH_WIDTH*NUM_LANES;
|
||||
localparam ODW = 8*TPL_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 [7:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe >> DPW_LOG2;
|
||||
wire [7:0] device_cfg_beats_per_multiframe_s;
|
||||
|
||||
wire [NUM_LANES-1:0] cgs_reset;
|
||||
wire [NUM_LANES-1:0] cgs_ready;
|
||||
|
@ -159,6 +169,7 @@ reg buffer_release_n = 1'b1;
|
|||
reg buffer_release_d1 = 1'b0;
|
||||
wire [NUM_LANES-1:0] buffer_ready_n;
|
||||
wire all_buffer_ready_n;
|
||||
wire dev_all_buffer_ready_n;
|
||||
|
||||
reg eof_reset = 1'b1;
|
||||
|
||||
|
@ -169,7 +180,7 @@ wire [CW-1:0] phy_notintable_r;
|
|||
wire [CW-1:0] phy_disperr_r;
|
||||
wire [NUM_LANES-1:0] phy_block_sync_r;
|
||||
|
||||
wire [DW-1:0] rx_data_s;
|
||||
wire [ODW-1:0] rx_data_s;
|
||||
|
||||
wire rx_valid_s = buffer_release_d1;
|
||||
|
||||
|
@ -182,14 +193,16 @@ wire [NUM_LANES-1:0] ifs_ready;
|
|||
wire event_data_phase;
|
||||
wire err_statistics_reset;
|
||||
|
||||
wire lmfc_edge_synced;
|
||||
|
||||
reg [NUM_LANES-1:0] frame_align_err_thresh_met = {NUM_LANES{1'b0}};
|
||||
reg [NUM_LANES-1:0] event_frame_alignment_error_per_lane = {NUM_LANES{1'b0}};
|
||||
|
||||
reg buffer_release_opportunity = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (lmfc_counter == cfg_buffer_delay ||
|
||||
cfg_buffer_early_release == 1'b1) begin
|
||||
always @(posedge device_clk) begin
|
||||
if (lmfc_counter == device_cfg_buffer_delay ||
|
||||
device_cfg_buffer_early_release == 1'b1) begin
|
||||
buffer_release_opportunity <= 1'b1;
|
||||
end else begin
|
||||
buffer_release_opportunity <= 1'b0;
|
||||
|
@ -198,12 +211,22 @@ end
|
|||
|
||||
assign all_buffer_ready_n = |(buffer_ready_n & ~cfg_lanes_disable);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_all_buffer_ready_cdc (
|
||||
.in_bits(all_buffer_ready_n),
|
||||
.out_clk(device_clk),
|
||||
.out_resetn(1'b1),
|
||||
.out_bits(dev_all_buffer_ready_n)
|
||||
);
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
if (device_reset == 1'b1) begin
|
||||
buffer_release_n <= 1'b1;
|
||||
end else begin
|
||||
if (buffer_release_opportunity == 1'b1) begin
|
||||
buffer_release_n <= all_buffer_ready_n;
|
||||
buffer_release_n <= dev_all_buffer_ready_n;
|
||||
end
|
||||
end
|
||||
buffer_release_d1 <= ~buffer_release_n;
|
||||
|
@ -234,31 +257,40 @@ pipeline_stage #(
|
|||
);
|
||||
|
||||
pipeline_stage #(
|
||||
.WIDTH(DW+1),
|
||||
.WIDTH(ODW+2),
|
||||
.REGISTERED(1)
|
||||
) i_output_pipeline_stage (
|
||||
.clk(clk),
|
||||
.clk(device_clk),
|
||||
.in({
|
||||
eof_reset,
|
||||
rx_data_s,
|
||||
rx_valid_s
|
||||
}),
|
||||
.out({
|
||||
eof_reset_d,
|
||||
rx_data,
|
||||
rx_valid
|
||||
})
|
||||
);
|
||||
|
||||
// If input and output widths are symmetric keep the calculation for backwards
|
||||
// compatibility of the software.
|
||||
assign device_cfg_beats_per_multiframe_s = (TPL_DATA_PATH_WIDTH == DATA_PATH_WIDTH) ?
|
||||
device_cfg_octets_per_multiframe >> DPW_LOG2 :
|
||||
device_cfg_beats_per_multiframe;
|
||||
|
||||
jesd204_lmfc #(
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH)
|
||||
) i_lmfc (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.clk(device_clk),
|
||||
.reset(device_reset),
|
||||
|
||||
.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),
|
||||
.cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
||||
.cfg_beats_per_multiframe(device_cfg_beats_per_multiframe_s),
|
||||
.cfg_lmfc_offset(device_cfg_lmfc_offset),
|
||||
.cfg_sysref_oneshot(device_cfg_sysref_oneshot),
|
||||
.cfg_sysref_disable(device_cfg_sysref_disable),
|
||||
|
||||
.sysref(sysref),
|
||||
.lmfc_edge(lmfc_edge),
|
||||
|
@ -268,17 +300,18 @@ jesd204_lmfc #(
|
|||
.lmc_quarter_edge(),
|
||||
.eoemb(),
|
||||
|
||||
.sysref_edge(event_sysref_edge),
|
||||
.sysref_alignment_error(event_sysref_alignment_error)
|
||||
.sysref_edge(device_event_sysref_edge),
|
||||
.sysref_alignment_error(device_event_sysref_alignment_error)
|
||||
);
|
||||
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH (TPL_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),
|
||||
.clk (device_clk),
|
||||
.reset (eof_reset_d),
|
||||
.cfg_beats_per_multiframe (device_cfg_beats_per_multiframe_s),
|
||||
.cfg_octets_per_multiframe (device_cfg_octets_per_multiframe),
|
||||
.cfg_octets_per_frame (device_cfg_octets_per_frame),
|
||||
.sof (rx_sof),
|
||||
.eof (rx_eof),
|
||||
.somf (rx_somf),
|
||||
|
@ -288,6 +321,16 @@ jesd204_frame_mark #(
|
|||
generate
|
||||
genvar i;
|
||||
|
||||
sync_event #(
|
||||
.NUM_OF_EVENTS (1),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_sync_lmfc (
|
||||
.in_clk(device_clk),
|
||||
.in_event(lmfc_edge),
|
||||
.out_clk(clk),
|
||||
.out_event(lmfc_edge_synced)
|
||||
);
|
||||
|
||||
if (LINK_MODE[0] == 1) begin : mode_8b10b
|
||||
|
||||
wire unexpected_lane_state_error;
|
||||
|
@ -307,7 +350,7 @@ jesd204_rx_ctrl #(
|
|||
.phy_ready(1'b1),
|
||||
.phy_en_char_align(phy_en_char_align),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.lmfc_edge(lmfc_edge_synced),
|
||||
.frame_align_err_thresh_met(frame_align_err_thresh_met),
|
||||
.sync(sync),
|
||||
|
||||
|
@ -330,21 +373,28 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
|
||||
localparam D_START = i * DATA_PATH_WIDTH*8;
|
||||
localparam D_STOP = D_START + DATA_PATH_WIDTH*8-1;
|
||||
localparam OD_START = i * TPL_DATA_PATH_WIDTH*8;
|
||||
localparam OD_STOP = OD_START + TPL_DATA_PATH_WIDTH*8-1;
|
||||
localparam C_START = i * DATA_PATH_WIDTH;
|
||||
localparam C_STOP = C_START + DATA_PATH_WIDTH-1;
|
||||
|
||||
jesd204_rx_lane #(
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.TPL_DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH),
|
||||
.CHAR_INFO_REGISTERED(CHAR_INFO_REGISTERED),
|
||||
.ALIGN_MUX_REGISTERED(ALIGN_MUX_REGISTERED),
|
||||
.SCRAMBLER_REGISTERED(SCRAMBLER_REGISTERED),
|
||||
.ELASTIC_BUFFER_SIZE(ELASTIC_BUFFER_SIZE),
|
||||
.ENABLE_FRAME_ALIGN_CHECK(ENABLE_FRAME_ALIGN_CHECK),
|
||||
.ENABLE_CHAR_REPLACE(ENABLE_CHAR_REPLACE)
|
||||
.ENABLE_CHAR_REPLACE(ENABLE_CHAR_REPLACE),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_lane (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_charisk(phy_charisk_r[C_STOP:C_START]),
|
||||
.phy_notintable(phy_notintable_r[C_STOP:C_START]),
|
||||
|
@ -355,7 +405,7 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
|
||||
.ifs_reset(ifs_reset[i]),
|
||||
|
||||
.rx_data(rx_data_s[D_STOP:D_START]),
|
||||
.rx_data(rx_data_s[OD_STOP:OD_START]),
|
||||
|
||||
.buffer_release_n(buffer_release_n),
|
||||
.buffer_ready_n(buffer_ready_n[i]),
|
||||
|
@ -452,6 +502,17 @@ end
|
|||
if (LINK_MODE[1] == 1) begin : mode_64b66b
|
||||
|
||||
wire [NUM_LANES-1:0] emb_lock;
|
||||
wire link_buffer_release_n;
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_buffer_release_cdc (
|
||||
.in_bits(buffer_release_n),
|
||||
.out_clk(clk),
|
||||
.out_resetn(1'b1),
|
||||
.out_bits(link_buffer_release_n)
|
||||
);
|
||||
|
||||
jesd204_rx_ctrl_64b #(
|
||||
.NUM_LANES(NUM_LANES)
|
||||
|
@ -465,7 +526,7 @@ jesd204_rx_ctrl_64b #(
|
|||
.emb_lock(emb_lock),
|
||||
|
||||
.all_emb_lock(all_emb_lock),
|
||||
.buffer_release_n(buffer_release_n),
|
||||
.buffer_release_n(link_buffer_release_n),
|
||||
|
||||
.status_state(status_ctrl_state),
|
||||
.event_unexpected_lane_state_error(event_unexpected_lane_state_error)
|
||||
|
@ -475,17 +536,24 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
|
||||
localparam D_START = i * DATA_PATH_WIDTH*8;
|
||||
localparam D_STOP = D_START + DATA_PATH_WIDTH*8-1;
|
||||
localparam TPL_D_START = i * TPL_DATA_PATH_WIDTH*8;
|
||||
localparam TPL_D_STOP = TPL_D_START + TPL_DATA_PATH_WIDTH*8-1;
|
||||
localparam H_START = i * 2;
|
||||
localparam H_STOP = H_START + 2-1;
|
||||
|
||||
wire [7:0] status_lane_skew;
|
||||
|
||||
jesd204_rx_lane_64b #(
|
||||
.ELASTIC_BUFFER_SIZE(ELASTIC_BUFFER_SIZE)
|
||||
.ELASTIC_BUFFER_SIZE(ELASTIC_BUFFER_SIZE),
|
||||
.TPL_DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_lane (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_header(phy_header_r[H_STOP:H_START]),
|
||||
.phy_block_sync(phy_block_sync_r[i]),
|
||||
|
@ -495,13 +563,13 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.cfg_rx_thresh_emb_err(5'd8),
|
||||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
|
||||
.rx_data(rx_data_s[D_STOP:D_START]),
|
||||
.rx_data(rx_data_s[TPL_D_STOP:TPL_D_START]),
|
||||
|
||||
.buffer_release_n(buffer_release_n),
|
||||
.buffer_ready_n(buffer_ready_n[i]),
|
||||
.all_buffer_ready_n(all_buffer_ready_n),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.lmfc_edge(lmfc_edge_synced),
|
||||
.emb_lock(emb_lock[i]),
|
||||
|
||||
.ctrl_err_statistics_reset(ctrl_err_statistics_reset),
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
<: setFileExtension ".xdc" :>
|
||||
<: setFileProcessingOrder late :>
|
||||
<: set sysref_iob [get_property PARAM_VALUE.SYSREF_IOB] :>
|
||||
<: set async_clk [getBooleanValue "ASYNC_CLK"] :>
|
||||
<: set link_mode [getBooleanValue "LINK_MODE"] :>
|
||||
|
||||
set_property ASYNC_REG TRUE \
|
||||
[get_cells {i_lmfc/sysref_d1_reg}] \
|
||||
|
@ -56,3 +58,42 @@ set_property ASYNC_REG TRUE \
|
|||
# predictable
|
||||
set_property IOB <=: $sysref_iob :> \
|
||||
[get_cells {i_lmfc/sysref_r_reg}]
|
||||
|
||||
<: if {$async_clk} { :>
|
||||
|
||||
set link_clk [get_clocks -of_objects [get_ports -quiet {clk}]]
|
||||
set device_clk [get_clocks -of_objects [get_ports -quiet {device_clk}]]
|
||||
|
||||
# sync bits
|
||||
set_false_path \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_all_buffer_ready_cdc* && IS_SEQUENTIAL}]
|
||||
|
||||
# sync event i_sync_lmfc
|
||||
set_false_path -quiet \
|
||||
-from $device_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_lmfc/i_sync_out* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_lmfc/i_sync_in* && IS_SEQUENTIAL}]
|
||||
|
||||
# elastic buffer distributed RAM
|
||||
set_false_path -quiet \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *rd_data_reg* \
|
||||
-filter {NAME =~ *i_elastic_buffer* && IS_SEQUENTIAL}]
|
||||
|
||||
<: if {$link_mode == 2} { :>
|
||||
# sync bits i_buffer_release_cdc 64b66b
|
||||
set_false_path \
|
||||
-from $device_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_buffer_release_cdc* && IS_SEQUENTIAL}]
|
||||
<: } :>
|
||||
|
||||
<: } :>
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ reg align_err;
|
|||
reg [DPW_LOG2*2:0] cur_align_err_cnt;
|
||||
wire [8:0] align_err_cnt_next;
|
||||
|
||||
wire [7:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe>>DPW_LOG2;
|
||||
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
|
@ -101,6 +102,7 @@ jesd204_frame_mark #(
|
|||
.clk (clk),
|
||||
.reset (reset),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_beats_per_multiframe (cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (),
|
||||
.eof (eof),
|
||||
|
|
|
@ -61,13 +61,17 @@ adi_ip_files jesd204_rx [list \
|
|||
"jesd204_rx_frame_align.v" \
|
||||
"jesd204_rx_constr.ttcl" \
|
||||
"jesd204_rx.v" \
|
||||
"../../common/ad_pack.v" \
|
||||
"bd/bd.tcl"
|
||||
]
|
||||
|
||||
adi_ip_properties_lite jesd204_rx
|
||||
adi_ip_ttcl jesd204_rx "jesd204_rx_constr.ttcl"
|
||||
adi_ip_bd jesd204_rx "bd/bd.tcl"
|
||||
|
||||
adi_ip_add_core_dependencies { \
|
||||
analog.com:user:jesd204_common:1.0 \
|
||||
analog.com:user:util_cdc:1.0 \
|
||||
}
|
||||
|
||||
set_property display_name "ADI JESD204 Receive" [ipx::current_core]
|
||||
|
@ -102,16 +106,19 @@ adi_add_bus "rx_cfg" "slave" \
|
|||
{ "cfg_links_disable" "links_disable" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
{ "cfg_sysref_disable" "sysref_disable" } \
|
||||
{ "cfg_buffer_delay" "buffer_delay" } \
|
||||
{ "cfg_buffer_early_release" "buffer_early_release" } \
|
||||
{ "cfg_disable_scrambler" "disable_scrambler" } \
|
||||
{ "cfg_disable_char_replacement" "disable_char_replacement" } \
|
||||
{ "cfg_frame_align_err_threshold" "frame_align_err_threshold" } \
|
||||
{ "device_cfg_octets_per_multiframe" "device_octets_per_multiframe" } \
|
||||
{ "device_cfg_octets_per_frame" "device_octets_per_frame" } \
|
||||
{ "device_cfg_beats_per_multiframe" "device_beats_per_multiframe" } \
|
||||
{ "device_cfg_lmfc_offset" "device_lmfc_offset" } \
|
||||
{ "device_cfg_sysref_oneshot" "device_sysref_oneshot" } \
|
||||
{ "device_cfg_sysref_disable" "device_sysref_disable" } \
|
||||
{ "device_cfg_buffer_delay" "device_buffer_delay" } \
|
||||
{ "device_cfg_buffer_early_release" "device_buffer_early_release" } \
|
||||
{ "ctrl_err_statistics_reset" "err_statistics_reset" } \
|
||||
{ "ctrl_err_statistics_mask" "err_statistics_mask" } \
|
||||
{ "cfg_disable_scrambler" "disable_scrambler" } \
|
||||
{ "cfg_frame_align_err_threshold" "frame_align_err_threshold" } \
|
||||
}
|
||||
|
||||
adi_add_bus "rx_status" "master" \
|
||||
|
@ -140,13 +147,14 @@ adi_add_bus "rx_event" "master" \
|
|||
"analog.com:interface:jesd204_rx_event_rtl:1.0" \
|
||||
"analog.com:interface:jesd204_rx_event:1.0" \
|
||||
{ \
|
||||
{ "event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "event_sysref_edge" "sysref_edge" } \
|
||||
{ "device_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "device_event_sysref_edge" "sysref_edge" } \
|
||||
{ "event_frame_alignment_error" "frame_alignment_error" } \
|
||||
{ "event_unexpected_lane_state_error" "unexpected_lane_state_error" } \
|
||||
}
|
||||
|
||||
adi_add_bus_clock "clk" "rx_cfg:rx_ilas_config:rx_event:rx_status:rx_data" "reset"
|
||||
adi_add_bus_clock "clk" "rx_cfg:rx_ilas_config:rx_event:rx_status" "reset"
|
||||
adi_add_bus_clock "device_clk" "rx_data" "device_reset"
|
||||
|
||||
adi_set_bus_dependency "rx_ilas_config" "rx_ilas_config" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.LINK_MODE')) = 1)"
|
||||
|
@ -198,5 +206,15 @@ set_property -dict [list \
|
|||
show_label true \
|
||||
] $param
|
||||
|
||||
set clk_group [ipgui::add_group -name {Clock Domain Configuration} -component $cc \
|
||||
-parent $page0 -display_name {Clock Domain Configuration}]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ASYNC_CLK" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $clk_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Link and Device Clock Asynchronous" \
|
||||
"widget" "checkBox" \
|
||||
] $p
|
||||
|
||||
ipx::create_xgui_files [ipx::current_core]
|
||||
ipx::save_core [ipx::current_core]
|
||||
|
|
|
@ -46,16 +46,21 @@
|
|||
|
||||
module jesd204_rx_lane #(
|
||||
parameter DATA_PATH_WIDTH = 4,
|
||||
parameter TPL_DATA_PATH_WIDTH = 4,
|
||||
parameter CHAR_INFO_REGISTERED = 0,
|
||||
parameter ALIGN_MUX_REGISTERED = 0,
|
||||
parameter SCRAMBLER_REGISTERED = 0,
|
||||
parameter ELASTIC_BUFFER_SIZE = 256,
|
||||
parameter ENABLE_FRAME_ALIGN_CHECK = 0,
|
||||
parameter ENABLE_CHAR_REPLACE = 0
|
||||
parameter ENABLE_CHAR_REPLACE = 0,
|
||||
parameter ASYNC_CLK = 0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input device_clk,
|
||||
input device_reset,
|
||||
|
||||
input [DATA_PATH_WIDTH*8-1:0] phy_data,
|
||||
input [DATA_PATH_WIDTH-1:0] phy_charisk,
|
||||
input [DATA_PATH_WIDTH-1:0] phy_notintable,
|
||||
|
@ -66,7 +71,7 @@ module jesd204_rx_lane #(
|
|||
|
||||
input ifs_reset,
|
||||
|
||||
output [DATA_PATH_WIDTH*8-1:0] rx_data,
|
||||
output [TPL_DATA_PATH_WIDTH*8-1:0] rx_data,
|
||||
|
||||
output buffer_ready_n,
|
||||
input buffer_release_n,
|
||||
|
@ -304,12 +309,17 @@ pipeline_stage #(
|
|||
);
|
||||
|
||||
elastic_buffer #(
|
||||
.WIDTH(DATA_PATH_WIDTH*8),
|
||||
.SIZE(ELASTIC_BUFFER_SIZE)
|
||||
.IWIDTH(DATA_PATH_WIDTH*8),
|
||||
.OWIDTH(TPL_DATA_PATH_WIDTH*8),
|
||||
.SIZE(ELASTIC_BUFFER_SIZE),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_elastic_buffer (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.wr_data(data_scrambled),
|
||||
.rd_data(rx_data),
|
||||
|
||||
|
|
|
@ -45,16 +45,21 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_rx_lane_64b #(
|
||||
parameter ELASTIC_BUFFER_SIZE = 256
|
||||
parameter ELASTIC_BUFFER_SIZE = 256,
|
||||
parameter TPL_DATA_PATH_WIDTH = 8,
|
||||
parameter ASYNC_CLK = 0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input device_clk,
|
||||
input device_reset,
|
||||
|
||||
input [63:0] phy_data,
|
||||
input [1:0] phy_header,
|
||||
input phy_block_sync,
|
||||
|
||||
output [63:0] rx_data,
|
||||
output [TPL_DATA_PATH_WIDTH*8-1:0] rx_data,
|
||||
|
||||
output reg buffer_ready_n = 'b1,
|
||||
input all_buffer_ready_n,
|
||||
|
@ -80,6 +85,7 @@ reg [11:0] crc12_calculated_prev;
|
|||
|
||||
wire [63:0] data_descrambled_s;
|
||||
wire [63:0] data_descrambled;
|
||||
wire [63:0] data_descrambled_reordered;
|
||||
wire [11:0] crc12_received;
|
||||
wire [11:0] crc12_calculated;
|
||||
|
||||
|
@ -108,7 +114,7 @@ jesd204_rx_header i_rx_header (
|
|||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
|
||||
.emb_lock(emb_lock),
|
||||
|
||||
|
||||
.valid_eomb(eomb),
|
||||
.valid_eoemb(eoemb),
|
||||
.crc12(crc12_received),
|
||||
|
@ -217,14 +223,19 @@ end
|
|||
|
||||
|
||||
elastic_buffer #(
|
||||
.WIDTH(64),
|
||||
.SIZE(ELASTIC_BUFFER_SIZE)
|
||||
.IWIDTH(64),
|
||||
.OWIDTH(TPL_DATA_PATH_WIDTH*8),
|
||||
.SIZE(ELASTIC_BUFFER_SIZE),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_elastic_buffer (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.wr_data(data_descrambled),
|
||||
.rd_data(rx_data_msb_s),
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
|
||||
.wr_data(data_descrambled_reordered),
|
||||
.rd_data(rx_data),
|
||||
|
||||
.ready_n(buffer_ready_n),
|
||||
.do_release_n(buffer_release_n)
|
||||
|
@ -242,7 +253,7 @@ end
|
|||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 64; i = i + 8) begin: g_link_data
|
||||
assign rx_data[i+:8] = rx_data_msb_s[64-1-i-:8];
|
||||
assign data_descrambled_reordered[i+:8] = data_descrambled[64-1-i-:8];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_ilas_config.xml
|
|||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_ilas_config_rtl.xml
|
||||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_status.xml
|
||||
XILINX_DEPS += ../../jesd204/interfaces/jesd204_tx_status_rtl.xml
|
||||
XILINX_DEPS += bd/bd.tcl
|
||||
|
||||
XILINX_LIB_DEPS += jesd204/jesd204_common
|
||||
XILINX_LIB_DEPS += util_cdc
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
proc init {cellpath otherInfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
bd::mark_propagate_override $ip \
|
||||
"ASYNC_CLK"
|
||||
|
||||
}
|
||||
|
||||
proc detect_async_clk { cellpath ip param_name clk_a clk_b } {
|
||||
set param_src [get_property "CONFIG.$param_name.VALUE_SRC" $ip]
|
||||
if {[string equal $param_src "USER"]} {
|
||||
return;
|
||||
}
|
||||
|
||||
set clk_domain_a [get_property CONFIG.CLK_DOMAIN $clk_a]
|
||||
set clk_domain_b [get_property CONFIG.CLK_DOMAIN $clk_b]
|
||||
set clk_freq_a [get_property CONFIG.FREQ_HZ $clk_a]
|
||||
set clk_freq_b [get_property CONFIG.FREQ_HZ $clk_b]
|
||||
set clk_phase_a [get_property CONFIG.PHASE $clk_a]
|
||||
set clk_phase_b [get_property CONFIG.PHASE $clk_b]
|
||||
|
||||
# Only mark it as sync if we can make sure that it is sync, if the
|
||||
# relationship of the clocks is unknown mark it as async
|
||||
if {$clk_domain_a != {} && $clk_domain_b != {} && \
|
||||
$clk_domain_a == $clk_domain_b && $clk_freq_a == $clk_freq_b && \
|
||||
$clk_phase_a == $clk_phase_b} {
|
||||
set clk_async 0
|
||||
} else {
|
||||
set clk_async 1
|
||||
}
|
||||
|
||||
set_property "CONFIG.$param_name" $clk_async $ip
|
||||
|
||||
}
|
||||
|
||||
proc propagate {cellpath otherinfo} {
|
||||
set ip [get_bd_cells $cellpath]
|
||||
|
||||
set link_clk [get_bd_pins "$ip/clk"]
|
||||
set device_clk [get_bd_pins "$ip/device_clk"]
|
||||
|
||||
detect_async_clk $cellpath $ip "ASYNC_CLK" $link_clk $device_clk
|
||||
}
|
||||
|
|
@ -51,11 +51,16 @@ module jesd204_tx #(
|
|||
parameter LINK_MODE = 1, // 2 - 64B/66B; 1 - 8B/10B
|
||||
/* Only 4 is supported at the moment for 8b/10b and 8 for 64b */
|
||||
parameter DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4,
|
||||
parameter ENABLE_CHAR_REPLACE = 1'b0
|
||||
parameter TPL_DATA_PATH_WIDTH = LINK_MODE[1] ? 8 : 4,
|
||||
parameter ENABLE_CHAR_REPLACE = 1'b0,
|
||||
parameter ASYNC_CLK = 1
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input device_clk,
|
||||
input device_reset,
|
||||
|
||||
output [DATA_PATH_WIDTH*8*NUM_LANES-1:0] phy_data,
|
||||
output [DATA_PATH_WIDTH*NUM_LANES-1:0] phy_charisk,
|
||||
output [2*NUM_LANES-1:0] phy_header,
|
||||
|
@ -66,21 +71,18 @@ module jesd204_tx #(
|
|||
|
||||
input [NUM_LINKS-1:0] sync,
|
||||
|
||||
input [DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data,
|
||||
input [TPL_DATA_PATH_WIDTH*8*NUM_LANES-1:0] tx_data,
|
||||
output tx_ready,
|
||||
output [DATA_PATH_WIDTH-1:0] tx_eof,
|
||||
output [DATA_PATH_WIDTH-1:0] tx_sof,
|
||||
output [DATA_PATH_WIDTH-1:0] tx_somf,
|
||||
output [DATA_PATH_WIDTH-1:0] tx_eomf,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] tx_eof,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] tx_sof,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] tx_somf,
|
||||
output [TPL_DATA_PATH_WIDTH-1:0] tx_eomf,
|
||||
input tx_valid,
|
||||
|
||||
input [NUM_LANES-1:0] cfg_lanes_disable,
|
||||
input [NUM_LINKS-1:0] cfg_links_disable,
|
||||
input [9:0] cfg_octets_per_multiframe,
|
||||
input [7:0] cfg_octets_per_frame,
|
||||
input [7:0] cfg_lmfc_offset,
|
||||
input cfg_sysref_oneshot,
|
||||
input cfg_sysref_disable,
|
||||
input cfg_continuous_cgs,
|
||||
input cfg_continuous_ilas,
|
||||
input cfg_skip_ilas,
|
||||
|
@ -88,14 +90,21 @@ module jesd204_tx #(
|
|||
input cfg_disable_char_replacement,
|
||||
input cfg_disable_scrambler,
|
||||
|
||||
input [9:0] device_cfg_octets_per_multiframe,
|
||||
input [7:0] device_cfg_octets_per_frame,
|
||||
input [7:0] device_cfg_beats_per_multiframe,
|
||||
input [7:0] device_cfg_lmfc_offset,
|
||||
input device_cfg_sysref_oneshot,
|
||||
input device_cfg_sysref_disable,
|
||||
|
||||
output ilas_config_rd,
|
||||
output [1:0] ilas_config_addr,
|
||||
input [NUM_LANES*DATA_PATH_WIDTH*8-1:0] ilas_config_data,
|
||||
|
||||
input ctrl_manual_sync_request,
|
||||
|
||||
output event_sysref_edge,
|
||||
output event_sysref_alignment_error,
|
||||
output device_event_sysref_edge,
|
||||
output device_event_sysref_alignment_error,
|
||||
|
||||
output [NUM_LINKS-1:0] status_sync,
|
||||
output [1:0] status_state
|
||||
|
@ -107,6 +116,8 @@ 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 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 :
|
||||
MAX_BEATS_PER_MULTIFRAME > 64 ? 7 :
|
||||
|
@ -140,35 +151,191 @@ reg [DATA_PATH_WIDTH-1:0] tx_sof_fm_d2;
|
|||
reg [DATA_PATH_WIDTH-1:0] tx_eof_fm_d2;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_somf_fm_d2;
|
||||
reg [DATA_PATH_WIDTH-1:0] tx_eomf_fm_d2;
|
||||
wire lmfc_edge_synced;
|
||||
wire lmc_edge;
|
||||
wire lmc_quarter_edge;
|
||||
wire eoemb;
|
||||
wire [DATA_PATH_WIDTH*8*NUM_LANES-1:0] gearbox_data;
|
||||
wire tx_ready_nx;
|
||||
wire link_lmfc_edge;
|
||||
wire link_lmfc_clk;
|
||||
wire device_lmfc_edge;
|
||||
wire device_lmfc_clk;
|
||||
wire device_lmc_edge;
|
||||
wire device_lmc_quarter_edge;
|
||||
wire device_eoemb;
|
||||
wire tx_next_mf_ready;
|
||||
wire link_tx_ready;
|
||||
|
||||
wire [7:0] cfg_beats_per_multiframe = cfg_octets_per_multiframe >> DPW_LOG2;
|
||||
wire [7:0] device_cfg_beats_per_multiframe_s;
|
||||
|
||||
// If input and output widths are symmetric keep the calculation for backwards
|
||||
// compatibility of the software.
|
||||
assign device_cfg_beats_per_multiframe_s = (TPL_DATA_PATH_WIDTH == DATA_PATH_WIDTH) ?
|
||||
device_cfg_octets_per_multiframe >> DPW_LOG2 :
|
||||
device_cfg_beats_per_multiframe;
|
||||
|
||||
jesd204_lmfc #(
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
.DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH)
|
||||
) i_lmfc (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.clk(device_clk),
|
||||
.reset(device_reset),
|
||||
|
||||
.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),
|
||||
.cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
||||
.cfg_lmfc_offset(device_cfg_lmfc_offset),
|
||||
.cfg_beats_per_multiframe(device_cfg_beats_per_multiframe_s),
|
||||
.cfg_sysref_oneshot(device_cfg_sysref_oneshot),
|
||||
.cfg_sysref_disable(device_cfg_sysref_disable),
|
||||
|
||||
.sysref(sysref),
|
||||
|
||||
.sysref_edge(event_sysref_edge),
|
||||
.sysref_alignment_error(event_sysref_alignment_error),
|
||||
.sysref_edge(device_event_sysref_edge),
|
||||
.sysref_alignment_error(device_event_sysref_alignment_error),
|
||||
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.lmfc_clk(lmfc_clk),
|
||||
.lmfc_edge(device_lmfc_edge),
|
||||
.lmfc_clk(device_lmfc_clk),
|
||||
.lmfc_counter(),
|
||||
.lmc_edge(lmc_edge),
|
||||
.lmc_quarter_edge(lmc_quarter_edge),
|
||||
.eoemb(eoemb)
|
||||
.lmc_edge(device_lmc_edge),
|
||||
.lmc_quarter_edge(device_lmc_quarter_edge),
|
||||
.eoemb(device_eoemb)
|
||||
);
|
||||
|
||||
generate
|
||||
if (ASYNC_CLK) begin : dual_lmfc_mode
|
||||
|
||||
reg link_lmfc_reset = 1'b1;
|
||||
reg device_lmfc_edge_d1 = 1'b0;
|
||||
reg device_tx_ready = 1'b0;
|
||||
|
||||
jesd204_lmfc #(
|
||||
.LINK_MODE(LINK_MODE),
|
||||
.DATA_PATH_WIDTH(DATA_PATH_WIDTH)
|
||||
) i_link_lmfc (
|
||||
.clk(clk),
|
||||
.reset(link_lmfc_reset),
|
||||
|
||||
.cfg_octets_per_multiframe(cfg_octets_per_multiframe),
|
||||
.cfg_lmfc_offset('h0),
|
||||
.cfg_beats_per_multiframe(cfg_beats_per_multiframe),
|
||||
.cfg_sysref_oneshot(1'b0),
|
||||
.cfg_sysref_disable(1'b1),
|
||||
|
||||
.sysref(sysref),
|
||||
|
||||
.sysref_edge(),
|
||||
.sysref_alignment_error(),
|
||||
|
||||
.lmfc_edge(link_lmfc_edge),
|
||||
.lmfc_clk(link_lmfc_clk),
|
||||
.lmfc_counter(),
|
||||
.lmc_edge(lmc_edge),
|
||||
.lmc_quarter_edge(lmc_quarter_edge),
|
||||
.eoemb(eoemb)
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_link_reset_done_cdc (
|
||||
.in_bits(~reset),
|
||||
.out_clk(device_clk),
|
||||
.out_resetn(~device_reset),
|
||||
.out_bits(link_reset_n)
|
||||
);
|
||||
|
||||
sync_event #(
|
||||
.NUM_OF_EVENTS (1)
|
||||
) i_sync_lmfc (
|
||||
.in_clk(device_clk),
|
||||
.in_event(device_lmfc_edge & link_reset_n),
|
||||
.out_clk(clk),
|
||||
.out_event(lmfc_edge_synced)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
link_lmfc_reset <= 1'b1;
|
||||
end else if (lmfc_edge_synced) begin
|
||||
link_lmfc_reset <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
jesd204_tx_gearbox #(
|
||||
.IN_DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH),
|
||||
.OUT_DATA_PATH_WIDTH(DATA_PATH_WIDTH),
|
||||
.NUM_LANES(NUM_LANES),
|
||||
.DEPTH(8)
|
||||
) i_tx_gearbox(
|
||||
.link_clk(clk),
|
||||
.reset(reset),
|
||||
.device_clk(device_clk),
|
||||
.device_reset(device_reset),
|
||||
.device_data(tx_data),
|
||||
.device_lmfc_edge(device_lmfc_edge_d1),
|
||||
.link_data(gearbox_data),
|
||||
.output_ready(tx_ready_nx)
|
||||
);
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
device_lmfc_edge_d1 <= device_lmfc_edge;
|
||||
end
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK(ASYNC_CLK)
|
||||
) i_next_mf_ready_cdc (
|
||||
.in_bits(tx_next_mf_ready),
|
||||
.out_clk(device_clk),
|
||||
.out_resetn(1'b1),
|
||||
.out_bits(device_tx_next_mf_ready)
|
||||
);
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
if (device_reset) begin
|
||||
device_tx_ready <= 1'b0;
|
||||
end else if (device_lmfc_edge & device_tx_next_mf_ready) begin
|
||||
device_tx_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
jesd204_frame_mark #(
|
||||
.DATA_PATH_WIDTH(TPL_DATA_PATH_WIDTH)
|
||||
) i_device_frame_mark (
|
||||
.clk(device_clk),
|
||||
.reset(~device_tx_ready),
|
||||
.cfg_octets_per_multiframe(device_cfg_octets_per_multiframe),
|
||||
.cfg_beats_per_multiframe(device_cfg_beats_per_multiframe_s),
|
||||
.cfg_octets_per_frame(device_cfg_octets_per_frame),
|
||||
.sof(tx_sof),
|
||||
.eof(tx_eof),
|
||||
.somf(tx_somf),
|
||||
.eomf(tx_eomf)
|
||||
);
|
||||
|
||||
assign tx_ready = device_tx_ready;
|
||||
|
||||
end else begin
|
||||
assign link_lmfc_edge = device_lmfc_edge;
|
||||
assign link_lmfc_clk = device_lmfc_clk;
|
||||
assign lmc_edge = device_lmc_edge;
|
||||
assign lmc_quarter_edge = device_lmc_quarter_edge;
|
||||
assign eoemb = device_eoemb;
|
||||
assign gearbox_data = tx_data;
|
||||
|
||||
assign tx_sof = (LINK_MODE == 1) ? tx_sof_fm_d2 : tx_sof_fm;
|
||||
assign tx_eof = (LINK_MODE == 1) ? tx_eof_fm_d2 : tx_eof_fm;
|
||||
assign tx_somf = (LINK_MODE == 1) ? tx_somf_fm_d2 : tx_somf_fm;
|
||||
assign tx_eomf = (LINK_MODE == 1) ? tx_eomf_fm_d2 : tx_eomf_fm;
|
||||
assign tx_ready = link_tx_ready;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign lmfc_edge = device_lmfc_edge;
|
||||
assign lmfc_clk = device_lmfc_clk;
|
||||
|
||||
assign frame_mark_reset = (LINK_MODE == 1) ? eof_gen_reset : ~tx_ready_64b_next;
|
||||
|
||||
jesd204_frame_mark #(
|
||||
|
@ -177,6 +344,7 @@ jesd204_frame_mark #(
|
|||
.clk (clk),
|
||||
.reset (frame_mark_reset),
|
||||
.cfg_octets_per_multiframe (cfg_octets_per_multiframe),
|
||||
.cfg_beats_per_multiframe (cfg_beats_per_multiframe),
|
||||
.cfg_octets_per_frame (cfg_octets_per_frame),
|
||||
.sof (tx_sof_fm),
|
||||
.eof (tx_eof_fm),
|
||||
|
@ -195,11 +363,6 @@ always @(posedge clk) begin
|
|||
tx_eomf_fm_d2 <= tx_eomf_fm_d1;
|
||||
end
|
||||
|
||||
assign tx_sof = (LINK_MODE == 1) ? tx_sof_fm_d2 : tx_sof_fm;
|
||||
assign tx_eof = (LINK_MODE == 1) ? tx_eof_fm_d2 : tx_eof_fm;
|
||||
assign tx_somf = (LINK_MODE == 1) ? tx_somf_fm_d2 : tx_somf_fm;
|
||||
assign tx_eomf = (LINK_MODE == 1) ? tx_eomf_fm_d2 : tx_eomf_fm;
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
|
||||
|
@ -227,7 +390,7 @@ jesd204_tx_ctrl #(
|
|||
.reset(reset),
|
||||
|
||||
.sync(sync),
|
||||
.lmfc_edge(lmfc_edge),
|
||||
.lmfc_edge(link_lmfc_edge),
|
||||
.somf(tx_somf_fm_d2),
|
||||
.somf_early2(tx_somf_fm),
|
||||
.eomf(tx_eomf_fm_d2),
|
||||
|
@ -235,7 +398,9 @@ jesd204_tx_ctrl #(
|
|||
.lane_cgs_enable(lane_cgs_enable),
|
||||
.eof_reset(eof_gen_reset),
|
||||
|
||||
.tx_ready(tx_ready),
|
||||
.tx_ready(link_tx_ready),
|
||||
.tx_ready_nx(tx_ready_nx),
|
||||
.tx_next_mf_ready(tx_next_mf_ready),
|
||||
|
||||
.ilas_data(ilas_data),
|
||||
.ilas_charisk(ilas_charisk),
|
||||
|
@ -278,8 +443,8 @@ for (i = 0; i < NUM_LANES; i = i + 1) begin: gen_lane
|
|||
.ilas_data(ilas_data[D_STOP:D_START]),
|
||||
.ilas_charisk(ilas_charisk[C_STOP:C_START]),
|
||||
|
||||
.tx_data(tx_data[D_STOP:D_START]),
|
||||
.tx_ready(tx_ready),
|
||||
.tx_data(gearbox_data[D_STOP:D_START]),
|
||||
.tx_ready(link_tx_ready),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
.phy_charisk(phy_charisk_r[C_STOP:C_START]),
|
||||
|
@ -305,7 +470,7 @@ if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.tx_data(tx_data[D_STOP:D_START]),
|
||||
.tx_data(gearbox_data[D_STOP:D_START]),
|
||||
.tx_ready(tx_ready_64b),
|
||||
|
||||
.phy_data(phy_data_r[D_STOP:D_START]),
|
||||
|
@ -321,7 +486,7 @@ if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|||
);
|
||||
end
|
||||
|
||||
assign tx_ready_64b_next = reset ? 1'b0 : (lmfc_edge || tx_ready_64b);
|
||||
assign tx_ready_64b_next = reset ? 1'b0 : (link_lmfc_edge || tx_ready_64b);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
|
@ -331,7 +496,10 @@ if (LINK_MODE[1] == 1) begin : mode_64b66b
|
|||
end
|
||||
end
|
||||
|
||||
assign tx_ready = tx_ready_64b;
|
||||
assign tx_ready_nx = tx_ready_64b_next;
|
||||
assign tx_next_mf_ready = 1'b1;
|
||||
|
||||
assign link_tx_ready = tx_ready_64b;
|
||||
// Link considered in DATA phase when SYSREF received and LEMC clock started
|
||||
// running
|
||||
assign status_state = {2{tx_ready_64b}};
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<: setFileExtension ".xdc" :>
|
||||
<: setFileProcessingOrder late :>
|
||||
<: set sysref_iob [get_property PARAM_VALUE.SYSREF_IOB] :>
|
||||
<: set async_clk [getBooleanValue "ASYNC_CLK"] :>
|
||||
|
||||
set_property ASYNC_REG TRUE \
|
||||
[get_cells {i_lmfc/sysref_d1_reg}] \
|
||||
|
@ -56,3 +57,45 @@ set_property ASYNC_REG TRUE \
|
|||
# predictable
|
||||
set_property IOB <=: $sysref_iob :> \
|
||||
[get_cells {i_lmfc/sysref_r_reg}]
|
||||
|
||||
<: if {$async_clk} { :>
|
||||
|
||||
set link_clk [get_clocks -of_objects [get_ports -quiet {clk}]]
|
||||
set device_clk [get_clocks -of_objects [get_ports -quiet {device_clk}]]
|
||||
|
||||
# sync event i_sync_lmfc
|
||||
set_false_path -quiet \
|
||||
-from $device_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_lmfc/i_sync_out* && IS_SEQUENTIAL}]
|
||||
|
||||
set_false_path -quiet \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_lmfc/i_sync_in* && IS_SEQUENTIAL}]
|
||||
|
||||
# sync bits i_next_mf_ready_cdc
|
||||
set_false_path \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_next_mf_ready_cdc* && IS_SEQUENTIAL}]
|
||||
|
||||
# sync bits i_link_reset_done_cdc
|
||||
set_false_path \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_link_reset_done_cdc* && IS_SEQUENTIAL}]
|
||||
|
||||
# sync bits gearbox/i_sync_ready
|
||||
set_false_path \
|
||||
-from $link_clk \
|
||||
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
|
||||
-filter {NAME =~ *i_sync_ready* && IS_SEQUENTIAL}]
|
||||
|
||||
# gearbox distributed RAM
|
||||
set_false_path -quiet \
|
||||
-from $device_clk \
|
||||
-to [get_cells -quiet -hier *mem_rd_data_reg* \
|
||||
-filter {NAME =~ *i_tx_gearbox* && IS_SEQUENTIAL}]
|
||||
|
||||
<: } :>
|
||||
|
|
|
@ -62,6 +62,8 @@ module jesd204_tx_ctrl #(
|
|||
output reg eof_reset,
|
||||
|
||||
output reg tx_ready,
|
||||
output tx_ready_nx,
|
||||
output tx_next_mf_ready,
|
||||
|
||||
output reg [DATA_PATH_WIDTH*8*NUM_LANES-1:0] ilas_data,
|
||||
output reg [DATA_PATH_WIDTH*NUM_LANES-1:0] ilas_charisk,
|
||||
|
@ -102,11 +104,11 @@ reg ilas_reset = 1'b1;
|
|||
reg ilas_data_reset = 1'b1;
|
||||
reg sync_request = 1'b0;
|
||||
reg sync_request_received = 1'b0;
|
||||
reg last_ilas_mframe = 1'b0;
|
||||
reg [7:0] mframe_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;
|
||||
|
||||
|
@ -123,6 +125,7 @@ i_cdc_sync (
|
|||
.out_resetn(1'b1),
|
||||
.out_bits(status_sync)
|
||||
);
|
||||
|
||||
assign status_sync_masked = status_sync | cfg_links_disable;
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
@ -235,6 +238,9 @@ always @(posedge clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
assign tx_next_mf_ready = sync_request_received & last_ilas_mframe & ~cfg_continuous_ilas;
|
||||
assign tx_ready_nx = tx_ready | (tx_next_mf_ready & lmfc_edge_d2);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ilas_reset == 1'b1) begin
|
||||
mframe_counter <= 'h00;
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
//
|
||||
// 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
|
||||
|
||||
// Constraints:
|
||||
// - IN_DATA_PATH_WIDTH >= OUT_DATA_PATH_WIDTH
|
||||
//
|
||||
|
||||
module jesd204_tx_gearbox #(
|
||||
parameter IN_DATA_PATH_WIDTH = 6,
|
||||
parameter OUT_DATA_PATH_WIDTH = 4,
|
||||
parameter NUM_LANES = 1,
|
||||
parameter DEPTH = 16
|
||||
) (
|
||||
input link_clk,
|
||||
input reset,
|
||||
input device_clk,
|
||||
input device_reset,
|
||||
input [NUM_LANES*IN_DATA_PATH_WIDTH*8-1:0] device_data,
|
||||
input device_lmfc_edge,
|
||||
output [NUM_LANES*OUT_DATA_PATH_WIDTH*8-1:0] link_data,
|
||||
input output_ready
|
||||
);
|
||||
|
||||
localparam MEM_W = IN_DATA_PATH_WIDTH*8*NUM_LANES;
|
||||
localparam D_LOG2 = $clog2(DEPTH);
|
||||
|
||||
reg [MEM_W-1:0] mem [0:DEPTH-1];
|
||||
reg [D_LOG2-1:0] in_addr ='h00;
|
||||
reg [D_LOG2-1:0] out_addr = 'b0;
|
||||
reg mem_rd_valid = 'b0;
|
||||
reg [MEM_W-1:0] mem_rd_data;
|
||||
|
||||
wire mem_wr_en = 1'b1;
|
||||
wire mem_rd_en;
|
||||
wire [D_LOG2-1:0] in_out_addr;
|
||||
wire [D_LOG2-1:0] out_in_addr;
|
||||
wire [NUM_LANES-1:0] unpacker_ready;
|
||||
wire output_ready_sync;
|
||||
|
||||
sync_bits i_sync_ready (
|
||||
.in_bits(output_ready),
|
||||
.out_resetn(~device_reset),
|
||||
.out_clk(device_clk),
|
||||
.out_bits(output_ready_sync)
|
||||
);
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
if (device_lmfc_edge & ~output_ready_sync) begin
|
||||
in_addr <= 'h01;
|
||||
end else if (mem_wr_en) begin
|
||||
in_addr <= in_addr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge device_clk) begin
|
||||
if (mem_wr_en) begin
|
||||
mem[in_addr] <= device_data;
|
||||
end
|
||||
end
|
||||
|
||||
assign mem_rd_en = output_ready&unpacker_ready[0];
|
||||
|
||||
always @(posedge link_clk) begin
|
||||
if (mem_rd_en) begin
|
||||
mem_rd_data <= mem[out_addr];
|
||||
end
|
||||
mem_rd_valid <= mem_rd_en;
|
||||
end
|
||||
|
||||
always @(posedge link_clk) begin
|
||||
if (reset) begin
|
||||
out_addr <= 'b0;
|
||||
end else if (mem_rd_en) begin
|
||||
out_addr <= out_addr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < NUM_LANES; i=i+1) begin: unpacker
|
||||
|
||||
ad_upack #(
|
||||
.I_W(IN_DATA_PATH_WIDTH),
|
||||
.O_W(OUT_DATA_PATH_WIDTH),
|
||||
.UNIT_W(8),
|
||||
.O_REG(0)
|
||||
) i_ad_upack (
|
||||
.clk(link_clk),
|
||||
.reset(reset),
|
||||
.idata(mem_rd_data[i*IN_DATA_PATH_WIDTH*8+:IN_DATA_PATH_WIDTH*8]),
|
||||
.ivalid(mem_rd_valid),
|
||||
.iready(unpacker_ready[i]),
|
||||
|
||||
.odata(link_data[i*OUT_DATA_PATH_WIDTH*8+:OUT_DATA_PATH_WIDTH*8]),
|
||||
.ovalid()
|
||||
);
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
@ -50,13 +50,17 @@ adi_ip_files jesd204_tx [list \
|
|||
"jesd204_tx_lane.v" \
|
||||
"jesd204_tx_lane_64b.v" \
|
||||
"jesd204_tx_header.v" \
|
||||
"jesd204_tx_gearbox.v" \
|
||||
"jesd204_tx_ctrl.v" \
|
||||
"jesd204_tx_constr.ttcl" \
|
||||
"jesd204_tx.v"
|
||||
"../../common/ad_upack.v" \
|
||||
"jesd204_tx.v" \
|
||||
"bd/bd.tcl"
|
||||
]
|
||||
|
||||
adi_ip_properties_lite jesd204_tx
|
||||
adi_ip_ttcl jesd204_tx "jesd204_tx_constr.ttcl"
|
||||
adi_ip_bd jesd204_tx "bd/bd.tcl"
|
||||
|
||||
adi_ip_add_core_dependencies { \
|
||||
analog.com:user:jesd204_common:1.0 \
|
||||
|
@ -93,15 +97,18 @@ adi_add_bus "tx_cfg" "slave" \
|
|||
{ "cfg_links_disable" "links_disable" } \
|
||||
{ "cfg_octets_per_multiframe" "octets_per_multiframe" } \
|
||||
{ "cfg_octets_per_frame" "octets_per_frame" } \
|
||||
{ "cfg_lmfc_offset" "lmfc_offset" } \
|
||||
{ "cfg_sysref_oneshot" "sysref_oneshot" } \
|
||||
{ "cfg_sysref_disable" "sysref_disable" } \
|
||||
{ "cfg_continuous_cgs" "continuous_cgs" } \
|
||||
{ "cfg_continuous_ilas" "continuous_ilas" } \
|
||||
{ "cfg_skip_ilas" "skip_ilas" } \
|
||||
{ "cfg_mframes_per_ilas" "mframes_per_ilas" } \
|
||||
{ "cfg_disable_char_replacement" "disable_char_replacement" } \
|
||||
{ "cfg_disable_scrambler" "disable_scrambler" } \
|
||||
{ "device_cfg_octets_per_multiframe" "device_octets_per_multiframe" } \
|
||||
{ "device_cfg_octets_per_frame" "device_octets_per_frame" } \
|
||||
{ "device_cfg_beats_per_multiframe" "device_beats_per_multiframe" } \
|
||||
{ "device_cfg_lmfc_offset" "device_lmfc_offset" } \
|
||||
{ "device_cfg_sysref_oneshot" "device_sysref_oneshot" } \
|
||||
{ "device_cfg_sysref_disable" "device_sysref_disable" } \
|
||||
}
|
||||
|
||||
adi_add_bus "tx_ilas_config" "master" \
|
||||
|
@ -117,8 +124,8 @@ adi_add_bus "tx_event" "master" \
|
|||
"analog.com:interface:jesd204_tx_event_rtl:1.0" \
|
||||
"analog.com:interface:jesd204_tx_event:1.0" \
|
||||
{ \
|
||||
{ "event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "event_sysref_edge" "sysref_edge" } \
|
||||
{ "device_event_sysref_alignment_error" "sysref_alignment_error" } \
|
||||
{ "device_event_sysref_edge" "sysref_edge" } \
|
||||
}
|
||||
|
||||
adi_add_bus "tx_status" "master" \
|
||||
|
@ -136,8 +143,9 @@ adi_add_bus "tx_ctrl" "slave" \
|
|||
{ "ctrl_manual_sync_request" "manual_sync_request" } \
|
||||
}
|
||||
|
||||
adi_add_bus_clock "clk" "tx_data:tx_cfg:tx_ilas_config:tx_event:tx_status:tx_ctrl" \
|
||||
"reset"
|
||||
adi_add_bus_clock "clk" "tx_cfg:tx_ilas_config:tx_event:tx_status:tx_ctrl" "reset"
|
||||
|
||||
adi_add_bus_clock "device_clk" "tx_data" "device_reset"
|
||||
|
||||
adi_set_bus_dependency "tx_ilas_config" "tx_ilas_config" \
|
||||
"(spirit:decode(id('MODELPARAM_VALUE.LINK_MODE')) = 1)"
|
||||
|
@ -186,5 +194,16 @@ set_property -dict [list \
|
|||
show_label true \
|
||||
] $param
|
||||
|
||||
|
||||
set clk_group [ipgui::add_group -name {Clock Domain Configuration} -component $cc \
|
||||
-parent $page0 -display_name {Clock Domain Configuration}]
|
||||
|
||||
set p [ipgui::get_guiparamspec -name "ASYNC_CLK" -component $cc]
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $clk_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Link and Device Clock Asynchronous" \
|
||||
"widget" "checkBox" \
|
||||
] $p
|
||||
|
||||
ipx::create_xgui_files [ipx::current_core]
|
||||
ipx::save_core [ipx::current_core]
|
||||
|
|
|
@ -69,6 +69,7 @@ proc adi_axi_jesd204_tx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
ad_ip_parameter "${ip_name}/tx" CONFIG.LINK_MODE $link_mode
|
||||
|
||||
ad_connect "${ip_name}/tx_axi/core_reset" "${ip_name}/tx/reset"
|
||||
ad_connect "${ip_name}/tx_axi/device_reset" "${ip_name}/tx/device_reset"
|
||||
if {$link_mode == 1} {ad_connect "${ip_name}/tx_axi/tx_ctrl" "${ip_name}/tx/tx_ctrl"}
|
||||
ad_connect "${ip_name}/tx_axi/tx_cfg" "${ip_name}/tx/tx_cfg"
|
||||
ad_connect "${ip_name}/tx/tx_event" "${ip_name}/tx_axi/tx_event"
|
||||
|
@ -87,14 +88,17 @@ proc adi_axi_jesd204_tx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
ad_connect "${ip_name}/tx_axi/irq" "${ip_name}/irq"
|
||||
|
||||
# JESD204 processing
|
||||
create_bd_pin -dir I -type clk "${ip_name}/link_clk"
|
||||
create_bd_pin -dir I -type clk "${ip_name}/device_clk"
|
||||
if {$link_mode == 1} {create_bd_pin -dir I -from [expr $num_links - 1] -to 0 "${ip_name}/sync"}
|
||||
create_bd_pin -dir I "${ip_name}/sysref"
|
||||
|
||||
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 "${ip_name}/tx_data"
|
||||
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/tx_axi/core_clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/tx/clk"
|
||||
ad_connect "${ip_name}/link_clk" "${ip_name}/tx_axi/core_clk"
|
||||
ad_connect "${ip_name}/link_clk" "${ip_name}/tx/clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/tx_axi/device_clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/tx/device_clk"
|
||||
if {$link_mode == 1} {ad_connect "${ip_name}/sync" "${ip_name}/tx/sync"}
|
||||
ad_connect "${ip_name}/sysref" "${ip_name}/tx/sysref"
|
||||
ad_connect "${ip_name}/tx_data" "${ip_name}/tx/tx_data"
|
||||
|
@ -143,6 +147,7 @@ proc adi_axi_jesd204_rx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
ad_ip_parameter "${ip_name}/rx" CONFIG.LINK_MODE $link_mode
|
||||
|
||||
ad_connect "${ip_name}/rx_axi/core_reset" "${ip_name}/rx/reset"
|
||||
ad_connect "${ip_name}/rx_axi/device_reset" "${ip_name}/rx/device_reset"
|
||||
ad_connect "${ip_name}/rx_axi/rx_cfg" "${ip_name}/rx/rx_cfg"
|
||||
ad_connect "${ip_name}/rx/rx_event" "${ip_name}/rx_axi/rx_event"
|
||||
ad_connect "${ip_name}/rx/rx_status" "${ip_name}/rx_axi/rx_status"
|
||||
|
@ -160,6 +165,7 @@ proc adi_axi_jesd204_rx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
ad_connect "${ip_name}/rx_axi/irq" "${ip_name}/irq"
|
||||
|
||||
# JESD204 processing
|
||||
create_bd_pin -dir I -type clk "${ip_name}/link_clk"
|
||||
create_bd_pin -dir I -type clk "${ip_name}/device_clk"
|
||||
if {$link_mode == 1} {create_bd_pin -dir O -from [expr $num_links - 1] -to 0 "${ip_name}/sync"}
|
||||
create_bd_pin -dir I "${ip_name}/sysref"
|
||||
|
@ -172,8 +178,10 @@ proc adi_axi_jesd204_rx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
create_bd_pin -dir O "${ip_name}/rx_data_tvalid"
|
||||
create_bd_pin -dir O -from [expr $num_lanes * 32 - 1] -to 0 "${ip_name}/rx_data_tdata"
|
||||
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/rx_axi/core_clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/rx/clk"
|
||||
ad_connect "${ip_name}/link_clk" "${ip_name}/rx_axi/core_clk"
|
||||
ad_connect "${ip_name}/link_clk" "${ip_name}/rx/clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/rx_axi/device_clk"
|
||||
ad_connect "${ip_name}/device_clk" "${ip_name}/rx/device_clk"
|
||||
if {$link_mode == 1} {ad_connect "${ip_name}/rx/sync" "${ip_name}/sync"}
|
||||
ad_connect "${ip_name}/sysref" "${ip_name}/rx/sysref"
|
||||
# ad_connect "${ip_name}/phy_ready" "${ip_name}/rx/phy_ready"
|
||||
|
@ -204,7 +212,7 @@ proc adi_axi_jesd204_rx_create {ip_name num_lanes {num_links 1} {link_mode 1}} {
|
|||
|
||||
|
||||
# L M S N & NP
|
||||
proc adi_tpl_jesd204_tx_create {ip_name num_of_lanes num_of_converters samples_per_frame sample_width {link_layer_bytes_per_beat 4}} {
|
||||
proc adi_tpl_jesd204_tx_create {ip_name num_of_lanes num_of_converters samples_per_frame sample_width {link_layer_bytes_per_beat 4} {dma_sample_width 16}} {
|
||||
|
||||
|
||||
if {$num_of_lanes < 1 || $num_of_lanes > 16} {
|
||||
|
@ -250,6 +258,7 @@ proc adi_tpl_jesd204_tx_create {ip_name num_of_lanes num_of_converters samples_p
|
|||
CONVERTER_RESOLUTION $sample_width \
|
||||
BITS_PER_SAMPLE $sample_width \
|
||||
OCTETS_PER_BEAT $tpl_bytes_per_beat \
|
||||
DMA_BITS_PER_SAMPLE $dma_sample_width
|
||||
]
|
||||
|
||||
if {$num_of_converters > 1} {
|
||||
|
@ -332,7 +341,7 @@ proc adi_tpl_jesd204_tx_create {ip_name num_of_lanes num_of_converters samples_p
|
|||
|
||||
|
||||
# L M S N & NP
|
||||
proc adi_tpl_jesd204_rx_create {ip_name num_of_lanes num_of_converters samples_per_frame sample_width {link_layer_bytes_per_beat 4}} {
|
||||
proc adi_tpl_jesd204_rx_create {ip_name num_of_lanes num_of_converters samples_per_frame sample_width {link_layer_bytes_per_beat 4} {dma_sample_width 16}} {
|
||||
|
||||
|
||||
if {$num_of_lanes < 1 || $num_of_lanes > 16} {
|
||||
|
@ -381,15 +390,16 @@ proc adi_tpl_jesd204_rx_create {ip_name num_of_lanes num_of_converters samples_p
|
|||
CONVERTER_RESOLUTION $sample_width \
|
||||
BITS_PER_SAMPLE $sample_width \
|
||||
OCTETS_PER_BEAT $tpl_bytes_per_beat \
|
||||
DMA_BITS_PER_SAMPLE $dma_sample_width
|
||||
]
|
||||
|
||||
if {$num_of_converters > 1} {
|
||||
# Slicer cores
|
||||
for {set i 0} {$i < $num_of_converters} {incr i} {
|
||||
ad_ip_instance xlslice ${ip_name}/data_slice_$i [list \
|
||||
DIN_WIDTH [expr $sample_width*$samples_per_channel*$num_of_converters] \
|
||||
DIN_FROM [expr $sample_width*$samples_per_channel*($i+1)-1] \
|
||||
DIN_TO [expr $sample_width*$samples_per_channel*$i] \
|
||||
DIN_WIDTH [expr $dma_sample_width*$samples_per_channel*$num_of_converters] \
|
||||
DIN_FROM [expr $dma_sample_width*$samples_per_channel*($i+1)-1] \
|
||||
DIN_TO [expr $dma_sample_width*$samples_per_channel*$i] \
|
||||
]
|
||||
|
||||
ad_ip_instance xlslice "${ip_name}/enable_slice_${i}" [list \
|
||||
|
|
|
@ -180,12 +180,16 @@ proc ad_disconnect {p_name_1 p_name_2} {
|
|||
# \param[a_jesd] - name of the JESD204 link IP
|
||||
# \param[lane_map] - lane_map maps the logical lane $n onto the physical lane
|
||||
# $lane_map[$n], otherwise logical lane $n is mapped onto physical lane $n.
|
||||
# \param[device_clk] - define a custom device clock, should be a net name
|
||||
# \param[link_clk] - define a custom link clock, should be a net name
|
||||
# connected to the clock source. If not used, the rx|tx_clk_out_0 is used as
|
||||
# link clock. This should be lane rate / (encoder_ratio*datapath width in bits)
|
||||
# where encoder_ratio is 10/8 for 8b10b encoding or 66/64 for 64b66b link layer.
|
||||
# \param[device_clk] - define a custom device clock, should be a net name
|
||||
# connected to the clock source. If not used, the link_clk is used as
|
||||
# device clock
|
||||
#
|
||||
|
||||
proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {device_clk {}}} {
|
||||
proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {link_clk {}} {device_clk {}}} {
|
||||
|
||||
global xcvr_index
|
||||
global xcvr_tx_index
|
||||
|
@ -244,10 +248,18 @@ proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {device_clk {}}} {
|
|||
create_bd_port -dir I $m_sysref
|
||||
create_bd_port -from [expr $num_of_links - 1] -to 0 -dir ${ctrl_dir} $m_sync
|
||||
|
||||
if {$device_clk == {}} {
|
||||
set device_clk ${u_xcvr}/${txrx}_out_clk_${index}
|
||||
if {$link_clk == {}} {
|
||||
set link_clk ${u_xcvr}/${txrx}_out_clk_${index}
|
||||
set rst_gen [regsub -all "/" ${a_jesd}_rstgen "_"]
|
||||
set create_rst_gen 1
|
||||
} else {
|
||||
set rst_gen ${link_clk}_rstgen
|
||||
# Only create one reset gen per clock
|
||||
set create_rst_gen [expr {[get_bd_cells -quiet ${rst_gen}] == {}}]
|
||||
}
|
||||
|
||||
if {$device_clk == {}} {
|
||||
set device_clk $link_clk
|
||||
} else {
|
||||
set rst_gen ${device_clk}_rstgen
|
||||
# Only create one reset gen per clock
|
||||
|
@ -284,7 +296,7 @@ proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {device_clk {}}} {
|
|||
ad_connect ${a_xcvr}/up_cm_${n} ${u_xcvr}/up_cm_${n}
|
||||
}
|
||||
ad_connect ${a_xcvr}/up_ch_${n} ${u_xcvr}/up_${txrx}_${phys_lane}
|
||||
ad_connect ${device_clk} ${u_xcvr}/${txrx}_clk_${phys_lane}
|
||||
ad_connect ${link_clk} ${u_xcvr}/${txrx}_clk_${phys_lane}
|
||||
if {$phys_lane != {}} {
|
||||
if {$jesd204_type == 0} {
|
||||
ad_connect ${u_xcvr}/${txrx}_${phys_lane} ${a_jesd}/${txrx}_phy${n}
|
||||
|
@ -303,6 +315,7 @@ proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {device_clk {}}} {
|
|||
ad_connect ${a_jesd}/sysref $m_sysref
|
||||
ad_connect ${a_jesd}/sync $m_sync
|
||||
ad_connect ${device_clk} ${a_jesd}/device_clk
|
||||
ad_connect ${link_clk} ${a_jesd}/link_clk
|
||||
} else {
|
||||
ad_connect ${a_jesd}/${txrx}_sysref $m_sysref
|
||||
ad_connect ${a_jesd}/${txrx}_sync $m_sync
|
||||
|
|
Loading…
Reference in New Issue