ad_ip_jesd204_tpl_adc: make core more generic
parent
f41806c1be
commit
9c51f7f975
|
@ -6,6 +6,7 @@
|
|||
LIBRARY_NAME := ad_ip_jesd204_tpl_adc
|
||||
|
||||
GENERIC_DEPS += ../../common/ad_datafmt.v
|
||||
GENERIC_DEPS += ../../common/ad_perfect_shuffle.v
|
||||
GENERIC_DEPS += ../../common/ad_pnmon.v
|
||||
GENERIC_DEPS += ../../common/ad_rst.v
|
||||
GENERIC_DEPS += ../../common/ad_xcvr_rx_if.v
|
||||
|
|
|
@ -25,18 +25,21 @@
|
|||
|
||||
module ad_ip_jesd204_tpl_adc #(
|
||||
parameter ID = 0,
|
||||
parameter NUM_CHANNELS = 1,
|
||||
parameter CHANNEL_WIDTH = 14,
|
||||
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
|
||||
) (
|
||||
// jesd interface
|
||||
// link_clk is (line-rate/40)
|
||||
input link_clk,
|
||||
|
||||
input [3:0] link_sof,
|
||||
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||
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,
|
||||
|
||||
// dma interface
|
||||
|
@ -44,7 +47,7 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
output [NUM_CHANNELS-1:0] enable,
|
||||
|
||||
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,
|
||||
|
||||
// axi interface
|
||||
|
@ -78,8 +81,9 @@ module ad_ip_jesd204_tpl_adc #(
|
|||
);
|
||||
|
||||
// Number of samples per channel that are processed in parallel.
|
||||
// Assumes 2 octets per sample.
|
||||
localparam DATA_PATH_WIDTH = 2 * NUM_LANES / NUM_CHANNELS;
|
||||
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 = 16 * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||
|
||||
wire [NUM_CHANNELS-1:0] dfmt_enable_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 #(
|
||||
.NUM_CHANNELS (NUM_CHANNELS),
|
||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
||||
.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),
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
||||
) i_core (
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module ad_ip_jesd204_tpl_adc_channel #(
|
||||
parameter CHANNEL_WIDTH = 14,
|
||||
parameter CONVERTER_RESOLUTION = 14,
|
||||
parameter DATA_PATH_WIDTH = 2,
|
||||
parameter TWOS_COMPLEMENT = 1
|
||||
) (
|
||||
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,
|
||||
|
||||
|
@ -47,7 +47,7 @@ module ad_ip_jesd204_tpl_adc_channel #(
|
|||
// instantiations
|
||||
|
||||
ad_ip_jesd204_tpl_adc_pnmon #(
|
||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
||||
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
||||
) i_pnmon (
|
||||
|
@ -63,12 +63,12 @@ module ad_ip_jesd204_tpl_adc_channel #(
|
|||
genvar n;
|
||||
for (n = 0; n < DATA_PATH_WIDTH; n = n + 1) begin: g_datafmt
|
||||
ad_datafmt #(
|
||||
.DATA_WIDTH (CHANNEL_WIDTH)
|
||||
.DATA_WIDTH (CONVERTER_RESOLUTION)
|
||||
) i_ad_datafmt (
|
||||
.clk (clk),
|
||||
|
||||
.valid (1'b1),
|
||||
.data (raw_data[n*CHANNEL_WIDTH+:CHANNEL_WIDTH]),
|
||||
.data (raw_data[n*CONVERTER_RESOLUTION+:CONVERTER_RESOLUTION]),
|
||||
.valid_out (),
|
||||
.data_out (fmt_data[n*16+:16]),
|
||||
|
||||
|
|
|
@ -24,11 +24,16 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module ad_ip_jesd204_tpl_adc_core #(
|
||||
parameter NUM_CHANNELS = 1,
|
||||
parameter CHANNEL_WIDTH = 14,
|
||||
parameter NUM_LANES = 1,
|
||||
parameter TWOS_COMPLEMENT = 1,
|
||||
parameter DATA_PATH_WIDTH = 1
|
||||
parameter NUM_CHANNELS = 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,
|
||||
|
||||
|
@ -41,18 +46,19 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
output [NUM_CHANNELS-1:0] pn_oos,
|
||||
|
||||
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,
|
||||
output link_ready,
|
||||
input [3:0] link_sof,
|
||||
input [NUM_LANES*32-1:0] link_data
|
||||
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||
input [LINK_DATA_WIDTH-1:0] link_data
|
||||
);
|
||||
// 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;
|
||||
|
||||
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 adc_valid = {NUM_CHANNELS{1'b1}};
|
||||
|
@ -60,7 +66,12 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
ad_ip_jesd204_tpl_adc_deframer #(
|
||||
.NUM_LANES (NUM_LANES),
|
||||
.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 (
|
||||
.clk (clk),
|
||||
.link_sof (link_sof),
|
||||
|
@ -72,8 +83,8 @@ module ad_ip_jesd204_tpl_adc_core #(
|
|||
genvar i;
|
||||
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_channel
|
||||
ad_ip_jesd204_tpl_adc_channel #(
|
||||
.CHANNEL_WIDTH (CHANNEL_WIDTH),
|
||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||
.TWOS_COMPLEMENT (TWOS_COMPLEMENT)
|
||||
) i_channel (
|
||||
.clk (clk),
|
||||
|
|
|
@ -25,46 +25,76 @@
|
|||
|
||||
module ad_ip_jesd204_tpl_adc_deframer #(
|
||||
parameter NUM_LANES = 1,
|
||||
parameter NUM_CHANNELS = 1,
|
||||
parameter CHANNEL_WIDTH = 16
|
||||
parameter NUM_CHANNELS = 4,
|
||||
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
|
||||
// clk is (line-rate/40)
|
||||
|
||||
input clk,
|
||||
input [3:0] link_sof,
|
||||
input [NUM_LANES*32-1:0] link_data,
|
||||
input [OCTETS_PER_BEAT-1:0] link_sof,
|
||||
input [LINK_DATA_WIDTH-1:0] link_data,
|
||||
|
||||
// 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
|
||||
|
||||
genvar i;
|
||||
genvar j;
|
||||
generate
|
||||
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_deframer_outer
|
||||
for (j = 0; j < DATA_PATH_WIDTH; j = j + 1) begin: g_deframer_inner
|
||||
localparam k = j + i * DATA_PATH_WIDTH;
|
||||
localparam adc_lsb = k * CHANNEL_WIDTH;
|
||||
localparam oct0_lsb = HD ? ((i * H + j % H) * 64 + (j / H) * 8) : (k * 16);
|
||||
localparam oct1_lsb = oct0_lsb + OCT_OFFSET + TAIL_BITS;
|
||||
|
||||
assign adc_data[adc_lsb+:CHANNEL_WIDTH] = {
|
||||
link_data_s[oct0_lsb+:8],
|
||||
link_data_s[oct1_lsb+:8-TAIL_BITS]
|
||||
};
|
||||
/* Reorder octets MSB first */
|
||||
for (i = 0; i < LINK_DATA_WIDTH; i = i + 8) begin: g_adc_data
|
||||
assign link_data_msb_s[i+:8] = link_data_s[LINK_DATA_WIDTH-1-i-:8];
|
||||
end
|
||||
|
||||
/* Slice lanes into frames */
|
||||
ad_perfect_shuffle #(
|
||||
.NUM_GROUPS (NUM_LANES),
|
||||
.WORDS_PER_GROUP (FRAMES_PER_BEAT),
|
||||
.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
|
||||
endgenerate
|
||||
|
||||
|
@ -73,12 +103,15 @@ module ad_ip_jesd204_tpl_adc_deframer #(
|
|||
generate
|
||||
genvar n;
|
||||
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_ip_sof (link_sof),
|
||||
.rx_ip_data (link_data[n*32+:32]),
|
||||
.rx_ip_data (link_data[n*DW+:DW]),
|
||||
.rx_sof (),
|
||||
.rx_data (link_data_s[n*32+:32])
|
||||
.rx_data (link_data_s[n*DW+:DW])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
|
|
@ -25,9 +25,11 @@ package require qsys
|
|||
source ../../scripts/adi_env.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_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_datafmt.v \
|
||||
$ad_hdl_dir/library/common/up_axi.v \
|
||||
|
@ -50,11 +52,106 @@ ad_ip_files ad_ip_jesd204_tpl_adc [list \
|
|||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter ID INTEGER 0
|
||||
ad_ip_parameter NUM_CHANNELS INTEGER 1
|
||||
ad_ip_parameter CHANNEL_WIDTH INTEGER 14
|
||||
ad_ip_parameter NUM_LANES INTEGER 1
|
||||
ad_ip_parameter TWOS_COMPLEMENT INTEGER 1
|
||||
set group "General Configuration"
|
||||
|
||||
ad_ip_parameter ID INTEGER 0 true [list \
|
||||
DISPLAY_NAME "Core ID" \
|
||||
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
|
||||
|
||||
|
@ -66,6 +163,73 @@ add_interface link_clk clock end
|
|||
add_interface_port link_clk link_clk clk Input 1
|
||||
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
|
||||
|
||||
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_files ad_ip_jesd204_tpl_adc [list \
|
||||
"$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_datafmt.v" \
|
||||
"$ad_hdl_dir/library/common/up_axi.v" \
|
||||
|
@ -68,7 +69,10 @@ adi_add_bus_clock "link_clk" "link"
|
|||
foreach {p v} {
|
||||
"NUM_LANES" "1 2 3 4 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 \
|
||||
"value_validation_type" "list" \
|
||||
|
@ -87,15 +91,18 @@ set_property -dict [list \
|
|||
"display_name" "Core ID" \
|
||||
] $p
|
||||
|
||||
set framer_group [ipgui::add_group -name "JESD204 Framer Configuration" -component $cc \
|
||||
-parent $page0 -display_name "JESD204 Framer Cofiguration"]
|
||||
set framer_group [ipgui::add_group -name "JESD204 Deframer Configuration" -component $cc \
|
||||
-parent $page0 -display_name "JESD204 Deframer Cofiguration"]
|
||||
|
||||
set i 0
|
||||
|
||||
foreach {k v} { \
|
||||
"NUM_LANES" "Number of Lanes (L)" \
|
||||
"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]
|
||||
ipgui::move_param -component $cc -order $i $p -parent $framer_group
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
`timescale 1ns/100ps
|
||||
|
||||
module ad_ip_jesd204_tpl_adc_pnmon #(
|
||||
parameter CHANNEL_WIDTH = 16,
|
||||
parameter CONVERTER_RESOLUTION = 16,
|
||||
parameter DATA_PATH_WIDTH = 1,
|
||||
parameter TWOS_COMPLEMENT = 1
|
||||
) (
|
||||
input clk,
|
||||
|
||||
// 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
|
||||
output pn_oos,
|
||||
|
@ -41,7 +41,7 @@ module ad_ip_jesd204_tpl_adc_pnmon #(
|
|||
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
|
||||
localparam PN_W = DW > 22 ? DW : 22;
|
||||
|
@ -78,10 +78,10 @@ module ad_ip_jesd204_tpl_adc_pnmon #(
|
|||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_pn_swizzle
|
||||
localparam src_lsb = i * CHANNEL_WIDTH;
|
||||
localparam src_msb = src_lsb + CHANNEL_WIDTH - 1;
|
||||
localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * CHANNEL_WIDTH;
|
||||
localparam dst_msb = dst_lsb + CHANNEL_WIDTH - 1;
|
||||
localparam src_lsb = i * CONVERTER_RESOLUTION;
|
||||
localparam src_msb = src_lsb + CONVERTER_RESOLUTION - 1;
|
||||
localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * CONVERTER_RESOLUTION;
|
||||
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-1:dst_lsb] = data[src_msb-1:src_lsb];
|
||||
|
|
Loading…
Reference in New Issue