From 9c51f7f97551cba38d62f9f2e722cac1cacb5752 Mon Sep 17 00:00:00 2001 From: Laszlo Nagy Date: Fri, 26 Oct 2018 08:02:12 +0100 Subject: [PATCH] ad_ip_jesd204_tpl_adc: make core more generic --- .../jesd204/ad_ip_jesd204_tpl_adc/Makefile | 1 + .../ad_ip_jesd204_tpl_adc.v | 27 ++- .../ad_ip_jesd204_tpl_adc_channel.v | 10 +- .../ad_ip_jesd204_tpl_adc_core.v | 33 ++-- .../ad_ip_jesd204_tpl_adc_deframer.v | 85 ++++++--- .../ad_ip_jesd204_tpl_adc_hw.tcl | 176 +++++++++++++++++- .../ad_ip_jesd204_tpl_adc_ip.tcl | 15 +- .../ad_ip_jesd204_tpl_adc_pnmon.v | 14 +- 8 files changed, 293 insertions(+), 68 deletions(-) diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/Makefile b/library/jesd204/ad_ip_jesd204_tpl_adc/Makefile index a48ce481c..af2a0ffcc 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/Makefile +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/Makefile @@ -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 diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v index c9c94d30a..08f8ec1d0 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc.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 ( diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_channel.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_channel.v index 4d79fd36f..a3d0ff903 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_channel.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_channel.v @@ -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]), diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v index cfa2e89e9..b2de602ce 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_core.v @@ -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), diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v index a997e0c33..a5484de66 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_deframer.v @@ -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 diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl index 0b2cb49c2..19f2d9c5e 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_hw.tcl @@ -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 {} { diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl index 192ecc83e..824333af3 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_ip.tcl @@ -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 diff --git a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_pnmon.v b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_pnmon.v index 834ee0959..c77b7a82d 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_pnmon.v +++ b/library/jesd204/ad_ip_jesd204_tpl_adc/ad_ip_jesd204_tpl_adc_pnmon.v @@ -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];