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

View File

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

View File

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

View File

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

View File

@ -25,47 +25,77 @@
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
end
endgenerate
// frame-alignment
@ -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

View File

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

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

View File

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