ad_ip_jesd204_tpl_adc: make core more generic

main
Laszlo Nagy 2018-10-26 08:02:12 +01:00 committed by Laszlo Nagy
parent f41806c1be
commit 9c51f7f975
8 changed files with 293 additions and 68 deletions

View File

@ -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

View File

@ -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 (

View File

@ -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]),

View File

@ -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),

View File

@ -25,46 +25,76 @@
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;
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]
};
end 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 end
endgenerate endgenerate
@ -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

View File

@ -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 {} {

View File

@ -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

View File

@ -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];