ad_ip_jesd204_tpl_adc: make core more generic
parent
f41806c1be
commit
9c51f7f975
|
@ -6,6 +6,7 @@
|
||||||
LIBRARY_NAME := ad_ip_jesd204_tpl_adc
|
LIBRARY_NAME := ad_ip_jesd204_tpl_adc
|
||||||
|
|
||||||
GENERIC_DEPS += ../../common/ad_datafmt.v
|
GENERIC_DEPS += ../../common/ad_datafmt.v
|
||||||
|
GENERIC_DEPS += ../../common/ad_perfect_shuffle.v
|
||||||
GENERIC_DEPS += ../../common/ad_pnmon.v
|
GENERIC_DEPS += ../../common/ad_pnmon.v
|
||||||
GENERIC_DEPS += ../../common/ad_rst.v
|
GENERIC_DEPS += ../../common/ad_rst.v
|
||||||
GENERIC_DEPS += ../../common/ad_xcvr_rx_if.v
|
GENERIC_DEPS += ../../common/ad_xcvr_rx_if.v
|
||||||
|
|
|
@ -25,18 +25,21 @@
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_adc #(
|
module ad_ip_jesd204_tpl_adc #(
|
||||||
parameter ID = 0,
|
parameter ID = 0,
|
||||||
parameter NUM_CHANNELS = 1,
|
|
||||||
parameter CHANNEL_WIDTH = 14,
|
|
||||||
parameter NUM_LANES = 1,
|
parameter NUM_LANES = 1,
|
||||||
|
parameter NUM_CHANNELS = 4,
|
||||||
|
parameter SAMPLES_PER_FRAME = 1,
|
||||||
|
parameter CONVERTER_RESOLUTION = 14,
|
||||||
|
parameter BITS_PER_SAMPLE = 16,
|
||||||
|
parameter OCTETS_PER_BEAT = 4,
|
||||||
parameter TWOS_COMPLEMENT = 1
|
parameter TWOS_COMPLEMENT = 1
|
||||||
) (
|
) (
|
||||||
// jesd interface
|
// jesd interface
|
||||||
// link_clk is (line-rate/40)
|
// link_clk is (line-rate/40)
|
||||||
input link_clk,
|
input link_clk,
|
||||||
|
|
||||||
input [3:0] link_sof,
|
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||||
input link_valid,
|
input link_valid,
|
||||||
input [NUM_LANES*32-1:0] link_data,
|
input [NUM_LANES*8*OCTETS_PER_BEAT-1:0] link_data,
|
||||||
output link_ready,
|
output link_ready,
|
||||||
|
|
||||||
// dma interface
|
// dma interface
|
||||||
|
@ -44,7 +47,7 @@ module ad_ip_jesd204_tpl_adc #(
|
||||||
output [NUM_CHANNELS-1:0] enable,
|
output [NUM_CHANNELS-1:0] enable,
|
||||||
|
|
||||||
output [NUM_CHANNELS-1:0] adc_valid,
|
output [NUM_CHANNELS-1:0] adc_valid,
|
||||||
output [NUM_LANES*32-1:0] adc_data,
|
output [NUM_LANES*8*OCTETS_PER_BEAT-1:0] adc_data,
|
||||||
input adc_dovf,
|
input adc_dovf,
|
||||||
|
|
||||||
// axi interface
|
// axi interface
|
||||||
|
@ -78,8 +81,9 @@ module ad_ip_jesd204_tpl_adc #(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Number of samples per channel that are processed in parallel.
|
// Number of samples per channel that are processed in parallel.
|
||||||
// Assumes 2 octets per sample.
|
localparam DATA_PATH_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES / NUM_CHANNELS / BITS_PER_SAMPLE;
|
||||||
localparam DATA_PATH_WIDTH = 2 * NUM_LANES / NUM_CHANNELS;
|
localparam LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8;
|
||||||
|
localparam DMA_DATA_WIDTH = 16 * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||||
|
|
||||||
wire [NUM_CHANNELS-1:0] dfmt_enable_s;
|
wire [NUM_CHANNELS-1:0] dfmt_enable_s;
|
||||||
wire [NUM_CHANNELS-1:0] dfmt_sign_extend_s;
|
wire [NUM_CHANNELS-1:0] dfmt_sign_extend_s;
|
||||||
|
@ -133,9 +137,14 @@ module ad_ip_jesd204_tpl_adc #(
|
||||||
);
|
);
|
||||||
|
|
||||||
ad_ip_jesd204_tpl_adc_core #(
|
ad_ip_jesd204_tpl_adc_core #(
|
||||||
.NUM_CHANNELS (NUM_CHANNELS),
|
|
||||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
|
||||||
.NUM_LANES (NUM_LANES),
|
.NUM_LANES (NUM_LANES),
|
||||||
|
.NUM_CHANNELS (NUM_CHANNELS),
|
||||||
|
.BITS_PER_SAMPLE (BITS_PER_SAMPLE),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
|
.SAMPLES_PER_FRAME (SAMPLES_PER_FRAME),
|
||||||
|
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
||||||
|
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||||
|
.DMA_DATA_WIDTH (DMA_DATA_WIDTH),
|
||||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT),
|
.TWOS_COMPLEMENT (TWOS_COMPLEMENT),
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||||
) i_core (
|
) i_core (
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_adc_channel #(
|
module ad_ip_jesd204_tpl_adc_channel #(
|
||||||
parameter CHANNEL_WIDTH = 14,
|
parameter CONVERTER_RESOLUTION = 14,
|
||||||
parameter DATA_PATH_WIDTH = 2,
|
parameter DATA_PATH_WIDTH = 2,
|
||||||
parameter TWOS_COMPLEMENT = 1
|
parameter TWOS_COMPLEMENT = 1
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
|
|
||||||
input [CHANNEL_WIDTH*DATA_PATH_WIDTH-1:0] raw_data,
|
input [CONVERTER_RESOLUTION*DATA_PATH_WIDTH-1:0] raw_data,
|
||||||
|
|
||||||
output [16*DATA_PATH_WIDTH-1:0] fmt_data,
|
output [16*DATA_PATH_WIDTH-1:0] fmt_data,
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ module ad_ip_jesd204_tpl_adc_channel #(
|
||||||
// instantiations
|
// instantiations
|
||||||
|
|
||||||
ad_ip_jesd204_tpl_adc_pnmon #(
|
ad_ip_jesd204_tpl_adc_pnmon #(
|
||||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
||||||
) i_pnmon (
|
) i_pnmon (
|
||||||
|
@ -63,12 +63,12 @@ module ad_ip_jesd204_tpl_adc_channel #(
|
||||||
genvar n;
|
genvar n;
|
||||||
for (n = 0; n < DATA_PATH_WIDTH; n = n + 1) begin: g_datafmt
|
for (n = 0; n < DATA_PATH_WIDTH; n = n + 1) begin: g_datafmt
|
||||||
ad_datafmt #(
|
ad_datafmt #(
|
||||||
.DATA_WIDTH (CHANNEL_WIDTH)
|
.DATA_WIDTH (CONVERTER_RESOLUTION)
|
||||||
) i_ad_datafmt (
|
) i_ad_datafmt (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
|
|
||||||
.valid (1'b1),
|
.valid (1'b1),
|
||||||
.data (raw_data[n*CHANNEL_WIDTH+:CHANNEL_WIDTH]),
|
.data (raw_data[n*CONVERTER_RESOLUTION+:CONVERTER_RESOLUTION]),
|
||||||
.valid_out (),
|
.valid_out (),
|
||||||
.data_out (fmt_data[n*16+:16]),
|
.data_out (fmt_data[n*16+:16]),
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,16 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_adc_core #(
|
module ad_ip_jesd204_tpl_adc_core #(
|
||||||
parameter NUM_CHANNELS = 1,
|
|
||||||
parameter CHANNEL_WIDTH = 14,
|
|
||||||
parameter NUM_LANES = 1,
|
parameter NUM_LANES = 1,
|
||||||
parameter TWOS_COMPLEMENT = 1,
|
parameter NUM_CHANNELS = 1,
|
||||||
parameter DATA_PATH_WIDTH = 1
|
parameter SAMPLES_PER_FRAME = 1,
|
||||||
|
parameter CONVERTER_RESOLUTION = 14,
|
||||||
|
parameter 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 * 16 * NUM_CHANNELS,
|
||||||
|
parameter TWOS_COMPLEMENT = 1
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
|
|
||||||
|
@ -41,18 +46,19 @@ module ad_ip_jesd204_tpl_adc_core #(
|
||||||
output [NUM_CHANNELS-1:0] pn_oos,
|
output [NUM_CHANNELS-1:0] pn_oos,
|
||||||
|
|
||||||
output [NUM_CHANNELS-1:0] adc_valid,
|
output [NUM_CHANNELS-1:0] adc_valid,
|
||||||
output [NUM_LANES*32-1:0] adc_data,
|
output [DMA_DATA_WIDTH-1:0] adc_data,
|
||||||
|
|
||||||
input link_valid,
|
input link_valid,
|
||||||
output link_ready,
|
output link_ready,
|
||||||
input [3:0] link_sof,
|
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||||
input [NUM_LANES*32-1:0] link_data
|
input [LINK_DATA_WIDTH-1:0] link_data
|
||||||
);
|
);
|
||||||
// Raw and formated channel data widths
|
// Raw and formated channel data widths
|
||||||
localparam CDW_RAW = CHANNEL_WIDTH * DATA_PATH_WIDTH;
|
localparam CDW_RAW = CONVERTER_RESOLUTION * DATA_PATH_WIDTH;
|
||||||
|
localparam ADC_DATA_WIDTH = CDW_RAW * NUM_CHANNELS;
|
||||||
localparam CDW_FMT = 16 * DATA_PATH_WIDTH;
|
localparam CDW_FMT = 16 * DATA_PATH_WIDTH;
|
||||||
|
|
||||||
wire [NUM_CHANNELS*CHANNEL_WIDTH*DATA_PATH_WIDTH-1:0] raw_data_s;
|
wire [ADC_DATA_WIDTH-1:0] raw_data_s;
|
||||||
|
|
||||||
assign link_ready = 1'b1;
|
assign link_ready = 1'b1;
|
||||||
assign adc_valid = {NUM_CHANNELS{1'b1}};
|
assign adc_valid = {NUM_CHANNELS{1'b1}};
|
||||||
|
@ -60,7 +66,12 @@ module ad_ip_jesd204_tpl_adc_core #(
|
||||||
ad_ip_jesd204_tpl_adc_deframer #(
|
ad_ip_jesd204_tpl_adc_deframer #(
|
||||||
.NUM_LANES (NUM_LANES),
|
.NUM_LANES (NUM_LANES),
|
||||||
.NUM_CHANNELS (NUM_CHANNELS),
|
.NUM_CHANNELS (NUM_CHANNELS),
|
||||||
.CHANNEL_WIDTH (CHANNEL_WIDTH)
|
.BITS_PER_SAMPLE (BITS_PER_SAMPLE),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
|
.SAMPLES_PER_FRAME (SAMPLES_PER_FRAME),
|
||||||
|
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
||||||
|
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||||
|
.ADC_DATA_WIDTH (ADC_DATA_WIDTH)
|
||||||
) i_deframer (
|
) i_deframer (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.link_sof (link_sof),
|
.link_sof (link_sof),
|
||||||
|
@ -72,8 +83,8 @@ module ad_ip_jesd204_tpl_adc_core #(
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_channel
|
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_channel
|
||||||
ad_ip_jesd204_tpl_adc_channel #(
|
ad_ip_jesd204_tpl_adc_channel #(
|
||||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
||||||
) i_channel (
|
) i_channel (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
|
|
|
@ -25,47 +25,77 @@
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_adc_deframer #(
|
module ad_ip_jesd204_tpl_adc_deframer #(
|
||||||
parameter NUM_LANES = 1,
|
parameter NUM_LANES = 1,
|
||||||
parameter NUM_CHANNELS = 1,
|
parameter NUM_CHANNELS = 4,
|
||||||
parameter CHANNEL_WIDTH = 16
|
parameter BITS_PER_SAMPLE = 16,
|
||||||
|
parameter CONVERTER_RESOLUTION = 14,
|
||||||
|
parameter SAMPLES_PER_FRAME = 1,
|
||||||
|
parameter OCTETS_PER_BEAT = 8,
|
||||||
|
parameter LINK_DATA_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES,
|
||||||
|
parameter ADC_DATA_WIDTH = LINK_DATA_WIDTH * CONVERTER_RESOLUTION / BITS_PER_SAMPLE
|
||||||
) (
|
) (
|
||||||
// jesd interface
|
// jesd interface
|
||||||
// clk is (line-rate/40)
|
// clk is (line-rate/40)
|
||||||
|
|
||||||
input clk,
|
input clk,
|
||||||
input [3:0] link_sof,
|
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||||
input [NUM_LANES*32-1:0] link_data,
|
input [LINK_DATA_WIDTH-1:0] link_data,
|
||||||
|
|
||||||
// adc data output
|
// adc data output
|
||||||
|
|
||||||
output [NUM_LANES*CHANNEL_WIDTH*2-1:0] adc_data
|
output [ADC_DATA_WIDTH-1:0] adc_data
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam TAIL_BITS = (16 - CHANNEL_WIDTH);
|
|
||||||
localparam DATA_PATH_WIDTH = 2 * NUM_LANES / NUM_CHANNELS;
|
|
||||||
localparam H = NUM_LANES / NUM_CHANNELS / 2;
|
|
||||||
localparam HD = NUM_LANES > NUM_CHANNELS ? 1 : 0;
|
|
||||||
localparam OCT_OFFSET = HD ? 32 : 8;
|
|
||||||
|
|
||||||
wire [NUM_LANES*32-1:0] link_data_s;
|
localparam SAMPLES_PER_BEAT = ADC_DATA_WIDTH / CONVERTER_RESOLUTION;
|
||||||
|
localparam BITS_PER_CHANNEL_PER_FRAME = BITS_PER_SAMPLE * SAMPLES_PER_FRAME;
|
||||||
|
localparam BITS_PER_LANE_PER_FRAME = BITS_PER_CHANNEL_PER_FRAME *
|
||||||
|
NUM_CHANNELS / NUM_LANES;
|
||||||
|
localparam FRAMES_PER_BEAT = OCTETS_PER_BEAT * 8 / BITS_PER_LANE_PER_FRAME;
|
||||||
|
|
||||||
|
wire [LINK_DATA_WIDTH-1:0] link_data_s;
|
||||||
|
wire [LINK_DATA_WIDTH-1:0] link_data_msb_s;
|
||||||
|
wire [LINK_DATA_WIDTH-1:0] frame_data_s;
|
||||||
|
wire [LINK_DATA_WIDTH-1:0] adc_data_msb;
|
||||||
|
|
||||||
// data multiplex
|
// data multiplex
|
||||||
|
|
||||||
genvar i;
|
genvar i;
|
||||||
genvar j;
|
genvar j;
|
||||||
generate
|
generate
|
||||||
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_deframer_outer
|
/* Reorder octets MSB first */
|
||||||
for (j = 0; j < DATA_PATH_WIDTH; j = j + 1) begin: g_deframer_inner
|
for (i = 0; i < LINK_DATA_WIDTH; i = i + 8) begin: g_adc_data
|
||||||
localparam k = j + i * DATA_PATH_WIDTH;
|
assign link_data_msb_s[i+:8] = link_data_s[LINK_DATA_WIDTH-1-i-:8];
|
||||||
localparam adc_lsb = k * CHANNEL_WIDTH;
|
end
|
||||||
localparam oct0_lsb = HD ? ((i * H + j % H) * 64 + (j / H) * 8) : (k * 16);
|
|
||||||
localparam oct1_lsb = oct0_lsb + OCT_OFFSET + TAIL_BITS;
|
/* Slice lanes into frames */
|
||||||
|
ad_perfect_shuffle #(
|
||||||
assign adc_data[adc_lsb+:CHANNEL_WIDTH] = {
|
.NUM_GROUPS (NUM_LANES),
|
||||||
link_data_s[oct0_lsb+:8],
|
.WORDS_PER_GROUP (FRAMES_PER_BEAT),
|
||||||
link_data_s[oct1_lsb+:8-TAIL_BITS]
|
.WORD_WIDTH (BITS_PER_LANE_PER_FRAME)
|
||||||
};
|
) i_lanes_to_frames (
|
||||||
|
.data_in (link_data_msb_s),
|
||||||
|
.data_out (frame_data_s)
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Slice frames into channels */
|
||||||
|
ad_perfect_shuffle #(
|
||||||
|
.NUM_GROUPS (FRAMES_PER_BEAT),
|
||||||
|
.WORDS_PER_GROUP (NUM_CHANNELS),
|
||||||
|
.WORD_WIDTH (BITS_PER_CHANNEL_PER_FRAME)
|
||||||
|
) i_frames_to_channels (
|
||||||
|
.data_in (frame_data_s),
|
||||||
|
.data_out (adc_data_msb)
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Reorder samples LSB first and remove tail bits */
|
||||||
|
for (i = 0; i < SAMPLES_PER_BEAT; i = i + 1) begin: g_dac_data_msb
|
||||||
|
localparam src_w = BITS_PER_SAMPLE;
|
||||||
|
localparam dst_w = CONVERTER_RESOLUTION;
|
||||||
|
localparam src_msb = LINK_DATA_WIDTH - 1 - i * src_w ;
|
||||||
|
localparam dst_lsb = i * dst_w;
|
||||||
|
|
||||||
|
assign adc_data[dst_lsb+:dst_w] = adc_data_msb[src_msb-:dst_w];
|
||||||
end
|
end
|
||||||
end
|
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// frame-alignment
|
// frame-alignment
|
||||||
|
@ -73,12 +103,15 @@ module ad_ip_jesd204_tpl_adc_deframer #(
|
||||||
generate
|
generate
|
||||||
genvar n;
|
genvar n;
|
||||||
for (n = 0; n < NUM_LANES; n = n + 1) begin: g_xcvr_if
|
for (n = 0; n < NUM_LANES; n = n + 1) begin: g_xcvr_if
|
||||||
ad_xcvr_rx_if i_xcvr_if (
|
localparam DW = OCTETS_PER_BEAT * 8;
|
||||||
|
ad_xcvr_rx_if #(
|
||||||
|
.OCTETS_PER_BEAT (OCTETS_PER_BEAT)
|
||||||
|
) i_xcvr_if (
|
||||||
.rx_clk (clk),
|
.rx_clk (clk),
|
||||||
.rx_ip_sof (link_sof),
|
.rx_ip_sof (link_sof),
|
||||||
.rx_ip_data (link_data[n*32+:32]),
|
.rx_ip_data (link_data[n*DW+:DW]),
|
||||||
.rx_sof (),
|
.rx_sof (),
|
||||||
.rx_data (link_data_s[n*32+:32])
|
.rx_data (link_data_s[n*DW+:DW])
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
|
@ -25,9 +25,11 @@ package require qsys
|
||||||
source ../../scripts/adi_env.tcl
|
source ../../scripts/adi_env.tcl
|
||||||
source ../../scripts/adi_ip_alt.tcl
|
source ../../scripts/adi_ip_alt.tcl
|
||||||
|
|
||||||
ad_ip_create ad_ip_jesd204_tpl_adc {AXI RX JESD204 Transport Layer} p_ad_ip_jesd204_tpl_adc_elab
|
ad_ip_create ad_ip_jesd204_tpl_adc "JESD204 Transport Layer for ADCs" p_ad_ip_jesd204_tpl_adc_elab
|
||||||
|
set_module_property VALIDATION_CALLBACK p_ad_ip_jesd204_tpl_adc_validate
|
||||||
ad_ip_files ad_ip_jesd204_tpl_adc [list \
|
ad_ip_files ad_ip_jesd204_tpl_adc [list \
|
||||||
$ad_hdl_dir/library/common/ad_rst.v \
|
$ad_hdl_dir/library/common/ad_rst.v \
|
||||||
|
$ad_hdl_dir/library/common/ad_perfect_shuffle.v \
|
||||||
$ad_hdl_dir/library/common/ad_pnmon.v \
|
$ad_hdl_dir/library/common/ad_pnmon.v \
|
||||||
$ad_hdl_dir/library/common/ad_datafmt.v \
|
$ad_hdl_dir/library/common/ad_datafmt.v \
|
||||||
$ad_hdl_dir/library/common/up_axi.v \
|
$ad_hdl_dir/library/common/up_axi.v \
|
||||||
|
@ -50,11 +52,106 @@ ad_ip_files ad_ip_jesd204_tpl_adc [list \
|
||||||
|
|
||||||
# parameters
|
# parameters
|
||||||
|
|
||||||
ad_ip_parameter ID INTEGER 0
|
set group "General Configuration"
|
||||||
ad_ip_parameter NUM_CHANNELS INTEGER 1
|
|
||||||
ad_ip_parameter CHANNEL_WIDTH INTEGER 14
|
ad_ip_parameter ID INTEGER 0 true [list \
|
||||||
ad_ip_parameter NUM_LANES INTEGER 1
|
DISPLAY_NAME "Core ID" \
|
||||||
ad_ip_parameter TWOS_COMPLEMENT INTEGER 1
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
set group "JESD204 Deframer Configuration"
|
||||||
|
|
||||||
|
ad_ip_parameter NUM_LANES INTEGER 1 true [list \
|
||||||
|
DISPLAY_NAME "Number of Lanes (L)" \
|
||||||
|
DISPLAY_UNITS "lanes" \
|
||||||
|
ALLOWED_RANGES {1 2 3 4 8} \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter NUM_CHANNELS INTEGER 1 true [list \
|
||||||
|
DISPLAY_NAME "Number of Converters (M)" \
|
||||||
|
DISPLAY_UNITS "converters" \
|
||||||
|
ALLOWED_RANGES {1 2 4 6 8} \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter BITS_PER_SAMPLE INTEGER 16 false [list \
|
||||||
|
DISPLAY_NAME "Bits per Sample (N')" \
|
||||||
|
ALLOWED_RANGES {12 16} \
|
||||||
|
UNITS bits \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter CONVERTER_RESOLUTION INTEGER 16 true [list \
|
||||||
|
DISPLAY_NAME "Converter Resolution (N)" \
|
||||||
|
ALLOWED_RANGES {11 12 16} \
|
||||||
|
UNITS bits \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter ENABLE_SAMPLES_PER_FRAME_MANUAL BOOLEAN 0 false [list \
|
||||||
|
DISPLAY_NAME "Manual Samples per Frame" \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter SAMPLES_PER_FRAME INTEGER 1 true [list \
|
||||||
|
DISPLAY_NAME "Samples per Frame (S)" \
|
||||||
|
DISPLAY_UNITS "samples" \
|
||||||
|
ALLOWED_RANGES {1 2 3 4 6 8 12 16} \
|
||||||
|
DERIVED true \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter SAMPLES_PER_FRAME_MANUAL INTEGER 1 false [list \
|
||||||
|
DISPLAY_NAME "Samples per Frame (S)" \
|
||||||
|
DISPLAY_UNITS "samples" \
|
||||||
|
ALLOWED_RANGES {1 2 3 4 6 8 12 16} \
|
||||||
|
VISIBLE false \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter OCTETS_PER_FRAME INTEGER 1 false [list \
|
||||||
|
DISPLAY_NAME "Octets per Frame (F)" \
|
||||||
|
DISPLAY_UNITS "octets" \
|
||||||
|
ALLOWED_RANGES {1 2 4} \
|
||||||
|
DERIVED true \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
set group "Deframer Output Information"
|
||||||
|
|
||||||
|
# Parameters in this group are informative only and can be read back after the
|
||||||
|
# core has been configured to find out the expected layout of the input data.
|
||||||
|
# E.g.
|
||||||
|
# set NUM_OF_CHANNELS [get_instance_parameter_value jesd204_transport NUM_CHANNELS]
|
||||||
|
# set CHANNEL_DATA_WIDTH [get_instance_parameter_value jesd204_transport CHANNEL_DATA_WIDTH]
|
||||||
|
#
|
||||||
|
# add_instance util_adc_cpack util_cpack
|
||||||
|
# set_instance_parameter_values util_adc_cpack [list \
|
||||||
|
# CHANNEL_DATA_WIDTH $CHANNEL_DATA_WIDTH \
|
||||||
|
# NUM_OF_CHANNELS $NUM_OF_CHANNELS \
|
||||||
|
# ]
|
||||||
|
|
||||||
|
ad_ip_parameter SAMPLES_PER_CHANNEL INTEGER 1 false [list \
|
||||||
|
DISPLAY_NAME "Samples per Channel per Beat" \
|
||||||
|
DERIVED true \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
ad_ip_parameter CHANNEL_DATA_WIDTH INTEGER 1 false [list \
|
||||||
|
DISPLAY_NAME "Channel Data Width" \
|
||||||
|
UNITS bits \
|
||||||
|
DERIVED true \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
set group "Datapath Configuration"
|
||||||
|
|
||||||
|
ad_ip_parameter TWOS_COMPLEMENT boolean 1 true [list \
|
||||||
|
DISPLAY_NAME "Twos Complement" \
|
||||||
|
GROUP $group \
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# axi4 slave
|
# axi4 slave
|
||||||
|
|
||||||
|
@ -66,6 +163,73 @@ add_interface link_clk clock end
|
||||||
add_interface_port link_clk link_clk clk Input 1
|
add_interface_port link_clk link_clk clk Input 1
|
||||||
ad_alt_intf signal link_sof input 4 export
|
ad_alt_intf signal link_sof input 4 export
|
||||||
|
|
||||||
|
# We don't expect too large values for a and b, trivial implementation will do
|
||||||
|
proc gcd {a b} {
|
||||||
|
if {$a == $b} {
|
||||||
|
return $b
|
||||||
|
} elseif {$a > $b} {
|
||||||
|
return [gcd [expr $a - $b] $b]
|
||||||
|
} else {
|
||||||
|
return [gcd $a [expr $b - $a]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# validate
|
||||||
|
|
||||||
|
proc p_ad_ip_jesd204_tpl_adc_validate {} {
|
||||||
|
set L [get_parameter_value "NUM_LANES"]
|
||||||
|
set M [get_parameter_value "NUM_CHANNELS"]
|
||||||
|
set NP [get_parameter_value "BITS_PER_SAMPLE"]
|
||||||
|
set N [get_parameter_value "CONVERTER_RESOLUTION"]
|
||||||
|
set S_manual [get_parameter_value "SAMPLES_PER_FRAME_MANUAL"]
|
||||||
|
set enable_S_manual [get_parameter_value "ENABLE_SAMPLES_PER_FRAME_MANUAL"]
|
||||||
|
|
||||||
|
# With fixed values for M, L and N' all valid values for S and F have a
|
||||||
|
# constant ratio of S / F. Choose a ratio so that S and F are co-prime.
|
||||||
|
# Choosing values for F and S that have a common factor has higher latency
|
||||||
|
# and no added benefits.
|
||||||
|
#
|
||||||
|
# Since converters often support those higher latency modes still allow a
|
||||||
|
# manual override of the S parameter in case somebody wants to use those modes
|
||||||
|
# anyway.
|
||||||
|
#
|
||||||
|
# To be able to set samples per frame manually ENABLE_SAMPLES_PER_FRAME_MANUAL
|
||||||
|
# needs to be set to true and SAMPLES_PER_FRAME_MANUAL to the desired value.
|
||||||
|
#
|
||||||
|
# When manual sample per frame selection is enabled still verify that the
|
||||||
|
# selected value is valid.
|
||||||
|
|
||||||
|
set S_min [expr $L * 8]
|
||||||
|
set F_min [expr $M * $NP]
|
||||||
|
set common_factor [gcd $S_min $F_min]
|
||||||
|
set S_min [expr $S_min / $common_factor]
|
||||||
|
set F_min [expr $F_min / $common_factor]
|
||||||
|
|
||||||
|
if {$enable_S_manual} {
|
||||||
|
if {$S_manual % $S_min != 0} {
|
||||||
|
send_message ERROR "For framer configuration (L=$L, M=$M, NP=$NP) samples per frame (S) must be an integer multiple of $S_min"
|
||||||
|
set S $S_min
|
||||||
|
set F $F_min
|
||||||
|
} else {
|
||||||
|
set S $S_manual
|
||||||
|
set F [expr $S_manual * $M * $NP / $L / 8]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set S $S_min
|
||||||
|
set F $F_min
|
||||||
|
}
|
||||||
|
|
||||||
|
set_parameter_value OCTETS_PER_FRAME $F
|
||||||
|
set_parameter_value SAMPLES_PER_FRAME $S
|
||||||
|
|
||||||
|
set_parameter_property SAMPLES_PER_FRAME VISIBLE [expr !$enable_S_manual]
|
||||||
|
set_parameter_property SAMPLES_PER_FRAME_MANUAL VISIBLE $enable_S_manual
|
||||||
|
|
||||||
|
set_parameter_value SAMPLES_PER_CHANNEL [expr 4 * $S / $F]
|
||||||
|
set_parameter_value CHANNEL_DATA_WIDTH [expr 16 * (4 * $S / $F)]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
# elaborate
|
# elaborate
|
||||||
|
|
||||||
proc p_ad_ip_jesd204_tpl_adc_elab {} {
|
proc p_ad_ip_jesd204_tpl_adc_elab {} {
|
||||||
|
|
|
@ -27,6 +27,7 @@ source $ad_hdl_dir/library/scripts/adi_ip.tcl
|
||||||
adi_ip_create ad_ip_jesd204_tpl_adc
|
adi_ip_create ad_ip_jesd204_tpl_adc
|
||||||
adi_ip_files ad_ip_jesd204_tpl_adc [list \
|
adi_ip_files ad_ip_jesd204_tpl_adc [list \
|
||||||
"$ad_hdl_dir/library/common/ad_rst.v" \
|
"$ad_hdl_dir/library/common/ad_rst.v" \
|
||||||
|
"$ad_hdl_dir/library/common/ad_perfect_shuffle.v" \
|
||||||
"$ad_hdl_dir/library/common/ad_pnmon.v" \
|
"$ad_hdl_dir/library/common/ad_pnmon.v" \
|
||||||
"$ad_hdl_dir/library/common/ad_datafmt.v" \
|
"$ad_hdl_dir/library/common/ad_datafmt.v" \
|
||||||
"$ad_hdl_dir/library/common/up_axi.v" \
|
"$ad_hdl_dir/library/common/up_axi.v" \
|
||||||
|
@ -68,7 +69,10 @@ adi_add_bus_clock "link_clk" "link"
|
||||||
foreach {p v} {
|
foreach {p v} {
|
||||||
"NUM_LANES" "1 2 3 4 8" \
|
"NUM_LANES" "1 2 3 4 8" \
|
||||||
"NUM_CHANNELS" "1 2 4 6 8" \
|
"NUM_CHANNELS" "1 2 4 6 8" \
|
||||||
"CHANNEL_WIDTH" "12 14 16" \
|
"BITS_PER_SAMPLE" "12 16" \
|
||||||
|
"CONVERTER_RESOLUTION" "11 12 16" \
|
||||||
|
"SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \
|
||||||
|
"OCTETS_PER_BEAT" "4 8" \
|
||||||
} { \
|
} { \
|
||||||
set_property -dict [list \
|
set_property -dict [list \
|
||||||
"value_validation_type" "list" \
|
"value_validation_type" "list" \
|
||||||
|
@ -87,15 +91,18 @@ set_property -dict [list \
|
||||||
"display_name" "Core ID" \
|
"display_name" "Core ID" \
|
||||||
] $p
|
] $p
|
||||||
|
|
||||||
set framer_group [ipgui::add_group -name "JESD204 Framer Configuration" -component $cc \
|
set framer_group [ipgui::add_group -name "JESD204 Deframer Configuration" -component $cc \
|
||||||
-parent $page0 -display_name "JESD204 Framer Cofiguration"]
|
-parent $page0 -display_name "JESD204 Deframer Cofiguration"]
|
||||||
|
|
||||||
set i 0
|
set i 0
|
||||||
|
|
||||||
foreach {k v} { \
|
foreach {k v} { \
|
||||||
"NUM_LANES" "Number of Lanes (L)" \
|
"NUM_LANES" "Number of Lanes (L)" \
|
||||||
"NUM_CHANNELS" "Number of Conveters (M)" \
|
"NUM_CHANNELS" "Number of Conveters (M)" \
|
||||||
"CHANNEL_WIDTH" "Bits per Sample (N')" \
|
"BITS_PER_SAMPLE" "Bits per Sample (N')" \
|
||||||
|
"CONVERTER_RESOLUTION" "Converter Resolution (N)" \
|
||||||
|
"SAMPLES_PER_FRAME" "Samples per Frame (S)" \
|
||||||
|
"OCTETS_PER_BEAT" "Octets per Beat" \
|
||||||
} { \
|
} { \
|
||||||
set p [ipgui::get_guiparamspec -name $k -component $cc]
|
set p [ipgui::get_guiparamspec -name $k -component $cc]
|
||||||
ipgui::move_param -component $cc -order $i $p -parent $framer_group
|
ipgui::move_param -component $cc -order $i $p -parent $framer_group
|
||||||
|
|
|
@ -24,14 +24,14 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_adc_pnmon #(
|
module ad_ip_jesd204_tpl_adc_pnmon #(
|
||||||
parameter CHANNEL_WIDTH = 16,
|
parameter CONVERTER_RESOLUTION = 16,
|
||||||
parameter DATA_PATH_WIDTH = 1,
|
parameter DATA_PATH_WIDTH = 1,
|
||||||
parameter TWOS_COMPLEMENT = 1
|
parameter TWOS_COMPLEMENT = 1
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
|
|
||||||
// data interface
|
// data interface
|
||||||
input [CHANNEL_WIDTH*DATA_PATH_WIDTH-1:0] data,
|
input [CONVERTER_RESOLUTION*DATA_PATH_WIDTH-1:0] data,
|
||||||
|
|
||||||
// pn out of sync and error
|
// pn out of sync and error
|
||||||
output pn_oos,
|
output pn_oos,
|
||||||
|
@ -41,7 +41,7 @@ module ad_ip_jesd204_tpl_adc_pnmon #(
|
||||||
input [3:0] pn_seq_sel
|
input [3:0] pn_seq_sel
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam DW = DATA_PATH_WIDTH*CHANNEL_WIDTH-1;
|
localparam DW = DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1;
|
||||||
|
|
||||||
// Max width of largest PN and data width
|
// Max width of largest PN and data width
|
||||||
localparam PN_W = DW > 22 ? DW : 22;
|
localparam PN_W = DW > 22 ? DW : 22;
|
||||||
|
@ -78,10 +78,10 @@ module ad_ip_jesd204_tpl_adc_pnmon #(
|
||||||
generate
|
generate
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_pn_swizzle
|
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_pn_swizzle
|
||||||
localparam src_lsb = i * CHANNEL_WIDTH;
|
localparam src_lsb = i * CONVERTER_RESOLUTION;
|
||||||
localparam src_msb = src_lsb + CHANNEL_WIDTH - 1;
|
localparam src_msb = src_lsb + CONVERTER_RESOLUTION - 1;
|
||||||
localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * CHANNEL_WIDTH;
|
localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * CONVERTER_RESOLUTION;
|
||||||
localparam dst_msb = dst_lsb + CHANNEL_WIDTH - 1;
|
localparam dst_msb = dst_lsb + CONVERTER_RESOLUTION - 1;
|
||||||
|
|
||||||
assign pn_data_in_s[dst_msb] = tc ^ data[src_msb];
|
assign pn_data_in_s[dst_msb] = tc ^ data[src_msb];
|
||||||
assign pn_data_in_s[dst_msb-1:dst_lsb] = data[src_msb-1:src_lsb];
|
assign pn_data_in_s[dst_msb-1:dst_lsb] = data[src_msb-1:src_lsb];
|
||||||
|
|
Loading…
Reference in New Issue