ad_ip_jesd204_tpl_dac: Add support for modes with N or N' != 16
The ad_ip_jesd204_tpl_dac currently only supports JESD204 modes that have both N and N' set to 16. Newer DACs like the AD9172 support modes where N and N' are not equal to 16. Add support for these modes. The width of the internal channel data path is set to N, only processing as many bits as necessary. At the framer the data is up-sized to N' bits with tail bits inserted as necessary. This data is then passed to the link layer. The width at the DMA interface is kept at 16 bits per sample regardless of the configuration of either N or N'. This is done to keep the interface consistent with the existing infrastructure it will connect to like upack and DMA. The data is expected to the LSB aligned, the unused MSBs will be ignored. Same is true for the test-pattern data registers. These register keep their existing 16-bit layout, but unused MSBs will be ignored by the core. The PN generators are modified to create only N bits of data per sample. Note that while the core can now support modes with N' = 12 there is still the restriction that requires the number of frames per beat to be an even number. Which means that not all modes with N' = 12 can be supported yet. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>main
parent
a98bc88b84
commit
169f38e7d1
|
@ -132,6 +132,8 @@ module axi_ad9144 #(
|
||||||
.ID (ID),
|
.ID (ID),
|
||||||
.NUM_LANES (NUM_CHANNELS * 2),
|
.NUM_LANES (NUM_CHANNELS * 2),
|
||||||
.NUM_CHANNELS (NUM_CHANNELS),
|
.NUM_CHANNELS (NUM_CHANNELS),
|
||||||
|
.CONVERTER_RESOLUTION (16),
|
||||||
|
.BITS_PER_SAMPLE (16),
|
||||||
.SAMPLES_PER_FRAME (1),
|
.SAMPLES_PER_FRAME (1),
|
||||||
.DDS_TYPE (DAC_DDS_TYPE),
|
.DDS_TYPE (DAC_DDS_TYPE),
|
||||||
.DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
|
.DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
|
||||||
|
|
|
@ -92,6 +92,8 @@ module axi_ad9152 #(
|
||||||
.ID(ID),
|
.ID(ID),
|
||||||
.NUM_LANES(4),
|
.NUM_LANES(4),
|
||||||
.NUM_CHANNELS(2),
|
.NUM_CHANNELS(2),
|
||||||
|
.CONVERTER_RESOLUTION (16),
|
||||||
|
.BITS_PER_SAMPLE (16),
|
||||||
.SAMPLES_PER_FRAME (1),
|
.SAMPLES_PER_FRAME (1),
|
||||||
.DDS_TYPE (DAC_DDS_TYPE),
|
.DDS_TYPE (DAC_DDS_TYPE),
|
||||||
.DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
|
.DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
|
||||||
|
|
|
@ -28,6 +28,8 @@ module ad_ip_jesd204_tpl_dac #(
|
||||||
parameter NUM_LANES = 4,
|
parameter NUM_LANES = 4,
|
||||||
parameter NUM_CHANNELS = 2,
|
parameter NUM_CHANNELS = 2,
|
||||||
parameter SAMPLES_PER_FRAME = 1,
|
parameter SAMPLES_PER_FRAME = 1,
|
||||||
|
parameter CONVERTER_RESOLUTION = 16,
|
||||||
|
parameter BITS_PER_SAMPLE = 16,
|
||||||
parameter DDS_TYPE = 1,
|
parameter DDS_TYPE = 1,
|
||||||
parameter DDS_CORDIC_DW = 16,
|
parameter DDS_CORDIC_DW = 16,
|
||||||
parameter DDS_CORDIC_PHASE_DW = 16,
|
parameter DDS_CORDIC_PHASE_DW = 16,
|
||||||
|
@ -81,8 +83,9 @@ module ad_ip_jesd204_tpl_dac #(
|
||||||
/* Static for now */
|
/* Static for now */
|
||||||
localparam OCTETS_PER_BEAT = 4;
|
localparam OCTETS_PER_BEAT = 4;
|
||||||
|
|
||||||
localparam DATA_PATH_WIDTH = 2 * OCTETS_PER_BEAT * 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 LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8;
|
||||||
|
localparam DMA_DATA_WIDTH = 16 * DATA_PATH_WIDTH * NUM_CHANNELS;
|
||||||
|
|
||||||
// internal signals
|
// internal signals
|
||||||
|
|
||||||
|
@ -157,6 +160,7 @@ module ad_ip_jesd204_tpl_dac #(
|
||||||
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||||
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||||
|
.DMA_DATA_WIDTH (DMA_DATA_WIDTH),
|
||||||
.DDS_TYPE (DDS_TYPE),
|
.DDS_TYPE (DDS_TYPE),
|
||||||
.DDS_CORDIC_DW (DDS_CORDIC_DW),
|
.DDS_CORDIC_DW (DDS_CORDIC_DW),
|
||||||
.DDS_CORDIC_PHASE_DW (DDS_CORDIC_PHASE_DW)
|
.DDS_CORDIC_PHASE_DW (DDS_CORDIC_PHASE_DW)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
module ad_ip_jesd204_tpl_dac_channel #(
|
module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
parameter DATAPATH_DISABLE = 0,
|
parameter DATAPATH_DISABLE = 0,
|
||||||
parameter DATA_PATH_WIDTH = 4,
|
parameter DATA_PATH_WIDTH = 4,
|
||||||
|
parameter CONVERTER_RESOLUTION = 16,
|
||||||
parameter DDS_TYPE = 1,
|
parameter DDS_TYPE = 1,
|
||||||
parameter DDS_CORDIC_DW = 16,
|
parameter DDS_CORDIC_DW = 16,
|
||||||
parameter DDS_CORDIC_PHASE_DW = 16
|
parameter DDS_CORDIC_PHASE_DW = 16
|
||||||
|
@ -35,12 +36,12 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
input clk,
|
input clk,
|
||||||
|
|
||||||
input [DATA_PATH_WIDTH*16-1:0] dma_data,
|
input [DATA_PATH_WIDTH*16-1:0] dma_data,
|
||||||
output reg [DATA_PATH_WIDTH*16-1:0] dac_data = 'h00,
|
output reg [DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1:0] dac_data = 'h00,
|
||||||
|
|
||||||
// PN data
|
// PN data
|
||||||
|
|
||||||
input [DATA_PATH_WIDTH*16-1:0] pn7_data,
|
input [DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1:0] pn7_data,
|
||||||
input [DATA_PATH_WIDTH*16-1:0] pn15_data,
|
input [DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1:0] pn15_data,
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
|
|
||||||
|
@ -62,14 +63,18 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
output reg dac_enable = 1'b0
|
output reg dac_enable = 1'b0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localparam CR = CONVERTER_RESOLUTION;
|
||||||
|
localparam CHANNEL_DATA_WIDTH = DATA_PATH_WIDTH * CR;
|
||||||
|
|
||||||
// internal signals
|
// internal signals
|
||||||
|
|
||||||
wire [DATA_PATH_WIDTH*16-1:0] dac_dds_data_s;
|
wire [CHANNEL_DATA_WIDTH-1:0] dac_dds_data_s;
|
||||||
wire [DATA_PATH_WIDTH*16-1:0] dac_pat_data_s;
|
wire [CHANNEL_DATA_WIDTH-1:0] dac_dma_data_s;
|
||||||
|
wire [CHANNEL_DATA_WIDTH-1:0] dac_pat_data_s;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (DATA_PATH_WIDTH > 1) begin
|
if (DATA_PATH_WIDTH > 1) begin
|
||||||
assign dac_pat_data_s = {DATA_PATH_WIDTH/2{dac_pat_data_1,dac_pat_data_0}};
|
assign dac_pat_data_s = {DATA_PATH_WIDTH/2{dac_pat_data_1[0+:CR],dac_pat_data_0[0+:CR]}};
|
||||||
end else begin
|
end else begin
|
||||||
reg dac_pat_data_sel = 1'b0;
|
reg dac_pat_data_sel = 1'b0;
|
||||||
|
|
||||||
|
@ -82,7 +87,13 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
end
|
end
|
||||||
|
|
||||||
assign dac_pat_data_s = dac_pat_data_sel == 1'b0 ?
|
assign dac_pat_data_s = dac_pat_data_sel == 1'b0 ?
|
||||||
dac_pat_data_0 : dac_pat_data_1;
|
dac_pat_data_0[0+:CR] : dac_pat_data_1[0+:CR];
|
||||||
|
end
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
/* Data is expected to be LSB aligned, drop unused MSBs */
|
||||||
|
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_dac_dma_data
|
||||||
|
assign dac_dma_data_s[CR*i+:CR] = dma_data[16*i+:CR];
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
@ -96,7 +107,7 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
4'h5: dac_data <= ~pn15_data;
|
4'h5: dac_data <= ~pn15_data;
|
||||||
4'h4: dac_data <= ~pn7_data;
|
4'h4: dac_data <= ~pn7_data;
|
||||||
4'h3: dac_data <= 'h00;
|
4'h3: dac_data <= 'h00;
|
||||||
4'h2: dac_data <= dma_data;
|
4'h2: dac_data <= dac_dma_data_s;
|
||||||
4'h1: dac_data <= dac_pat_data_s;
|
4'h1: dac_data <= dac_pat_data_s;
|
||||||
default: dac_data <= dac_dds_data_s;
|
default: dac_data <= dac_dds_data_s;
|
||||||
endcase
|
endcase
|
||||||
|
@ -106,7 +117,7 @@ module ad_ip_jesd204_tpl_dac_channel #(
|
||||||
|
|
||||||
ad_dds #(
|
ad_dds #(
|
||||||
.DISABLE (DATAPATH_DISABLE),
|
.DISABLE (DATAPATH_DISABLE),
|
||||||
.DDS_DW (16),
|
.DDS_DW (CONVERTER_RESOLUTION),
|
||||||
.PHASE_DW (16),
|
.PHASE_DW (16),
|
||||||
.DDS_TYPE (DDS_TYPE),
|
.DDS_TYPE (DDS_TYPE),
|
||||||
.CORDIC_DW (DDS_CORDIC_DW),
|
.CORDIC_DW (DDS_CORDIC_DW),
|
||||||
|
|
|
@ -27,10 +27,13 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
parameter DATAPATH_DISABLE = 0,
|
parameter DATAPATH_DISABLE = 0,
|
||||||
parameter NUM_LANES = 1,
|
parameter NUM_LANES = 1,
|
||||||
parameter NUM_CHANNELS = 1,
|
parameter NUM_CHANNELS = 1,
|
||||||
|
parameter BITS_PER_SAMPLE = 16,
|
||||||
|
parameter CONVERTER_RESOLUTION = 16,
|
||||||
parameter SAMPLES_PER_FRAME = 1,
|
parameter SAMPLES_PER_FRAME = 1,
|
||||||
parameter OCTETS_PER_BEAT = 4,
|
parameter OCTETS_PER_BEAT = 4,
|
||||||
parameter DATA_PATH_WIDTH = 4,
|
parameter DATA_PATH_WIDTH = 4,
|
||||||
parameter LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8,
|
parameter LINK_DATA_WIDTH = NUM_LANES * OCTETS_PER_BEAT * 8,
|
||||||
|
parameter DMA_DATA_WIDTH = DATA_PATH_WIDTH * 16 * NUM_CHANNELS,
|
||||||
parameter DDS_TYPE = 1,
|
parameter DDS_TYPE = 1,
|
||||||
parameter DDS_CORDIC_DW = 16,
|
parameter DDS_CORDIC_DW = 16,
|
||||||
parameter DDS_CORDIC_PHASE_DW = 16
|
parameter DDS_CORDIC_PHASE_DW = 16
|
||||||
|
@ -44,7 +47,7 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
|
|
||||||
// dma interface
|
// dma interface
|
||||||
output [NUM_CHANNELS-1:0] dac_valid,
|
output [NUM_CHANNELS-1:0] dac_valid,
|
||||||
input [LINK_DATA_WIDTH-1:0] dac_ddata,
|
input [DMA_DATA_WIDTH-1:0] dac_ddata,
|
||||||
|
|
||||||
// Configuration interface
|
// Configuration interface
|
||||||
|
|
||||||
|
@ -66,21 +69,28 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
output [NUM_CHANNELS-1:0] enable
|
output [NUM_CHANNELS-1:0] enable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localparam DAC_CDW = CONVERTER_RESOLUTION * DATA_PATH_WIDTH;
|
||||||
|
localparam DAC_DATA_WIDTH = DAC_CDW * NUM_CHANNELS;
|
||||||
|
localparam DMA_CDW = DATA_PATH_WIDTH * 16;
|
||||||
|
|
||||||
assign link_valid = 1'b1;
|
assign link_valid = 1'b1;
|
||||||
|
|
||||||
wire [LINK_DATA_WIDTH-1:0] dac_data_s;
|
wire [DAC_DATA_WIDTH-1:0] dac_data_s;
|
||||||
|
|
||||||
wire [DATA_PATH_WIDTH*16-1:0] pn7_data;
|
wire [DAC_CDW-1:0] pn7_data;
|
||||||
wire [DATA_PATH_WIDTH*16-1:0] pn15_data;
|
wire [DAC_CDW-1:0] pn15_data;
|
||||||
|
|
||||||
// device interface
|
// device interface
|
||||||
|
|
||||||
ad_ip_jesd204_tpl_dac_framer #(
|
ad_ip_jesd204_tpl_dac_framer #(
|
||||||
.NUM_LANES (NUM_LANES),
|
.NUM_LANES (NUM_LANES),
|
||||||
.NUM_CHANNELS (NUM_CHANNELS),
|
.NUM_CHANNELS (NUM_CHANNELS),
|
||||||
|
.BITS_PER_SAMPLE (BITS_PER_SAMPLE),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
.SAMPLES_PER_FRAME (SAMPLES_PER_FRAME),
|
.SAMPLES_PER_FRAME (SAMPLES_PER_FRAME),
|
||||||
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
.OCTETS_PER_BEAT (OCTETS_PER_BEAT),
|
||||||
.LINK_DATA_WIDTH (LINK_DATA_WIDTH)
|
.LINK_DATA_WIDTH (LINK_DATA_WIDTH),
|
||||||
|
.DAC_DATA_WIDTH (DAC_DATA_WIDTH)
|
||||||
) i_framer (
|
) i_framer (
|
||||||
.link_data (link_data),
|
.link_data (link_data),
|
||||||
.dac_data (dac_data_s)
|
.dac_data (dac_data_s)
|
||||||
|
@ -88,7 +98,8 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
|
|
||||||
// PN generator
|
// PN generator
|
||||||
ad_ip_jesd204_tpl_dac_pn #(
|
ad_ip_jesd204_tpl_dac_pn #(
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION)
|
||||||
) i_pn_gen (
|
) i_pn_gen (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (dac_sync),
|
.reset (dac_sync),
|
||||||
|
@ -101,13 +112,13 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
|
|
||||||
assign dac_valid = {NUM_CHANNELS{1'b1}};
|
assign dac_valid = {NUM_CHANNELS{1'b1}};
|
||||||
|
|
||||||
localparam CDW = DATA_PATH_WIDTH * 16;
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
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_dac_channel #(
|
ad_ip_jesd204_tpl_dac_channel #(
|
||||||
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
|
||||||
|
.CONVERTER_RESOLUTION (CONVERTER_RESOLUTION),
|
||||||
.DATAPATH_DISABLE (DATAPATH_DISABLE),
|
.DATAPATH_DISABLE (DATAPATH_DISABLE),
|
||||||
.DDS_TYPE (DDS_TYPE),
|
.DDS_TYPE (DDS_TYPE),
|
||||||
.DDS_CORDIC_DW (DDS_CORDIC_DW),
|
.DDS_CORDIC_DW (DDS_CORDIC_DW),
|
||||||
|
@ -115,8 +126,8 @@ module ad_ip_jesd204_tpl_dac_core #(
|
||||||
) i_channel (
|
) i_channel (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.dac_enable (enable[i]),
|
.dac_enable (enable[i]),
|
||||||
.dac_data (dac_data_s[CDW*i+:CDW]),
|
.dac_data (dac_data_s[DAC_CDW*i+:DAC_CDW]),
|
||||||
.dma_data (dac_ddata[CDW*i+:CDW]),
|
.dma_data (dac_ddata[DMA_CDW*i+:DMA_CDW]),
|
||||||
|
|
||||||
.pn7_data (pn7_data),
|
.pn7_data (pn7_data),
|
||||||
.pn15_data (pn15_data),
|
.pn15_data (pn15_data),
|
||||||
|
|
|
@ -26,9 +26,12 @@
|
||||||
module ad_ip_jesd204_tpl_dac_framer #(
|
module ad_ip_jesd204_tpl_dac_framer #(
|
||||||
parameter NUM_LANES = 8,
|
parameter NUM_LANES = 8,
|
||||||
parameter NUM_CHANNELS = 4,
|
parameter NUM_CHANNELS = 4,
|
||||||
|
parameter BITS_PER_SAMPLE = 16,
|
||||||
|
parameter CONVERTER_RESOLUTION = 16,
|
||||||
parameter SAMPLES_PER_FRAME = 2,
|
parameter SAMPLES_PER_FRAME = 2,
|
||||||
parameter OCTETS_PER_BEAT = 4,
|
parameter OCTETS_PER_BEAT = 4,
|
||||||
parameter LINK_DATA_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES
|
parameter LINK_DATA_WIDTH = OCTETS_PER_BEAT * 8 * NUM_LANES,
|
||||||
|
parameter DAC_DATA_WIDTH = LINK_DATA_WIDTH * CONVERTER_RESOLUTION / BITS_PER_SAMPLE
|
||||||
) (
|
) (
|
||||||
// jesd interface
|
// jesd interface
|
||||||
|
|
||||||
|
@ -36,7 +39,7 @@ module ad_ip_jesd204_tpl_dac_framer #(
|
||||||
|
|
||||||
// dac interface
|
// dac interface
|
||||||
|
|
||||||
input [LINK_DATA_WIDTH-1:0] dac_data
|
input [DAC_DATA_WIDTH-1:0] dac_data
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,7 +47,7 @@ module ad_ip_jesd204_tpl_dac_framer #(
|
||||||
* JESD204 link expects for the specified framer configuration.
|
* JESD204 link expects for the specified framer configuration.
|
||||||
*
|
*
|
||||||
* The input sample data in dac_data is expected to be grouped by converter.
|
* The input sample data in dac_data is expected to be grouped by converter.
|
||||||
* The first sample is in the LSBs.
|
* The first sample is in the LSBs. Each sample has CONVERTER_RESOLUTION bits.
|
||||||
*
|
*
|
||||||
* Or in other words the data in dac_data is expected to have the following
|
* Or in other words the data in dac_data is expected to have the following
|
||||||
* layout.
|
* layout.
|
||||||
|
@ -86,12 +89,12 @@ module ad_ip_jesd204_tpl_dac_framer #(
|
||||||
* ordered in either case. That means lower bits are in the LSBs.
|
* ordered in either case. That means lower bits are in the LSBs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
localparam BITS_PER_SAMPLE = 16;
|
localparam FRAMES_PER_BEAT = OCTETS_PER_BEAT * 8 / BITS_PER_LANE_PER_FRAME;
|
||||||
localparam FRAMES_PER_BEAT = 8 * OCTETS_PER_BEAT / BITS_PER_LANE_PER_FRAME;
|
localparam SAMPLES_PER_BEAT = DAC_DATA_WIDTH / CONVERTER_RESOLUTION;
|
||||||
localparam SAMPLES_PER_BEAT = LINK_DATA_WIDTH / 16;
|
|
||||||
localparam BITS_PER_CHANNEL_PER_FRAME = BITS_PER_SAMPLE * SAMPLES_PER_FRAME;
|
localparam BITS_PER_CHANNEL_PER_FRAME = BITS_PER_SAMPLE * SAMPLES_PER_FRAME;
|
||||||
localparam BITS_PER_LANE_PER_FRAME = BITS_PER_CHANNEL_PER_FRAME *
|
localparam BITS_PER_LANE_PER_FRAME = BITS_PER_CHANNEL_PER_FRAME *
|
||||||
NUM_CHANNELS / NUM_LANES;
|
NUM_CHANNELS / NUM_LANES;
|
||||||
|
localparam TAIL_BITS = BITS_PER_SAMPLE - CONVERTER_RESOLUTION;
|
||||||
|
|
||||||
wire [LINK_DATA_WIDTH-1:0] link_data_msb_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] frame_data_s;
|
||||||
|
@ -100,13 +103,17 @@ module ad_ip_jesd204_tpl_dac_framer #(
|
||||||
generate
|
generate
|
||||||
genvar i;
|
genvar i;
|
||||||
genvar j;
|
genvar j;
|
||||||
/* Reorder samples MSB first */
|
/* Reorder samples MSB first and insert tail bits */
|
||||||
for (i = 0; i < SAMPLES_PER_BEAT; i = i + 1) begin: g_dac_data_msb
|
for (i = 0; i < SAMPLES_PER_BEAT; i = i + 1) begin: g_dac_data_msb
|
||||||
localparam w = BITS_PER_SAMPLE;
|
localparam src_w = CONVERTER_RESOLUTION;
|
||||||
localparam src_lsb = i * w;
|
localparam dst_w = BITS_PER_SAMPLE;
|
||||||
localparam dst_msb = LINK_DATA_WIDTH - 1 - src_lsb;
|
localparam src_lsb = i * src_w;
|
||||||
|
localparam dst_msb = LINK_DATA_WIDTH - 1 - i * dst_w;
|
||||||
|
|
||||||
assign dac_data_msb[dst_msb-:w] = dac_data[src_lsb+:w];
|
assign dac_data_msb[dst_msb-:src_w] = dac_data[src_lsb+:src_w];
|
||||||
|
if (TAIL_BITS > 0) begin
|
||||||
|
assign dac_data_msb[dst_msb-src_w-:TAIL_BITS] = {TAIL_BITS{1'b0}};
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
/* Slice channel and pack it into frames */
|
/* Slice channel and pack it into frames */
|
||||||
|
|
|
@ -81,6 +81,20 @@ ad_ip_parameter NUM_CHANNELS INTEGER 1 true [list \
|
||||||
GROUP $group \
|
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 SAMPLES_PER_FRAME INTEGER 1 true [list \
|
ad_ip_parameter SAMPLES_PER_FRAME INTEGER 1 true [list \
|
||||||
DISPLAY_NAME "Samples per Frame (S)" \
|
DISPLAY_NAME "Samples per Frame (S)" \
|
||||||
DISPLAY_UNITS "samples" \
|
DISPLAY_UNITS "samples" \
|
||||||
|
@ -141,22 +155,25 @@ proc p_ad_ip_jesd204_tpl_dac_elab {} {
|
||||||
|
|
||||||
# read core parameters
|
# read core parameters
|
||||||
|
|
||||||
set m_num_of_lanes [get_parameter_value "NUM_LANES"]
|
set L [get_parameter_value "NUM_LANES"]
|
||||||
set m_num_of_channels [get_parameter_value "NUM_CHANNELS"]
|
set M [get_parameter_value "NUM_CHANNELS"]
|
||||||
set channel_bus_width [expr 32*$m_num_of_lanes/$m_num_of_channels]
|
set NP [get_parameter_value "BITS_PER_SAMPLE"]
|
||||||
|
|
||||||
|
# The DMA interface is always 16-bits per sample, regardless of NP
|
||||||
|
set channel_bus_width [expr 16 * (32 * $L / ($M * $NP))]
|
||||||
|
|
||||||
# link layer interface
|
# link layer interface
|
||||||
|
|
||||||
add_interface link_data avalon_streaming source
|
add_interface link_data avalon_streaming source
|
||||||
add_interface_port link_data link_data data output [expr 32*$m_num_of_lanes]
|
add_interface_port link_data link_data data output [expr 32 * $L]
|
||||||
add_interface_port link_data link_valid valid output 1
|
add_interface_port link_data link_valid valid output 1
|
||||||
add_interface_port link_data link_ready ready input 1
|
add_interface_port link_data link_ready ready input 1
|
||||||
set_interface_property link_data associatedClock link_clk
|
set_interface_property link_data associatedClock link_clk
|
||||||
set_interface_property link_data dataBitsPerSymbol [expr 32*$m_num_of_lanes]
|
set_interface_property link_data dataBitsPerSymbol [expr 32 * $L]
|
||||||
|
|
||||||
# dma interface
|
# dma interface
|
||||||
|
|
||||||
for {set i 0} {$i < $m_num_of_channels} {incr i} {
|
for {set i 0} {$i < $M} {incr i} {
|
||||||
add_interface dac_ch_$i conduit end
|
add_interface dac_ch_$i conduit end
|
||||||
add_interface_port dac_ch_$i dac_enable_$i enable output 1
|
add_interface_port dac_ch_$i dac_enable_$i enable output 1
|
||||||
set_port_property dac_enable_$i fragment_list [format "enable(%d:%d)" $i $i]
|
set_port_property dac_enable_$i fragment_list [format "enable(%d:%d)" $i $i]
|
||||||
|
|
|
@ -86,6 +86,8 @@ foreach p {DDS_CORDIC_DW DDS_CORDIC_PHASE_DW} {
|
||||||
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" \
|
||||||
|
"BITS_PER_SAMPLE" "12 16" \
|
||||||
|
"CONVERTER_RESOLUTION" "11 12 16" \
|
||||||
"SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \
|
"SAMPLES_PER_FRAME" "1 2 3 4 6 8 12 16" \
|
||||||
} { \
|
} { \
|
||||||
set_property -dict [list \
|
set_property -dict [list \
|
||||||
|
@ -113,6 +115,8 @@ 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)" \
|
||||||
|
"BITS_PER_SAMPLE" "Bits per Sample (N')" \
|
||||||
|
"CONVERTER_RESOLUTION" "Converter Resolution (N)" \
|
||||||
"SAMPLES_PER_FRAME" "Samples per Frame (S)" \
|
"SAMPLES_PER_FRAME" "Samples per Frame (S)" \
|
||||||
} { \
|
} { \
|
||||||
set p [ipgui::get_guiparamspec -name $k -component $cc]
|
set p [ipgui::get_guiparamspec -name $k -component $cc]
|
||||||
|
|
|
@ -24,26 +24,33 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module ad_ip_jesd204_tpl_dac_pn #(
|
module ad_ip_jesd204_tpl_dac_pn #(
|
||||||
parameter DATA_PATH_WIDTH = 4
|
parameter DATA_PATH_WIDTH = 4,
|
||||||
|
parameter CONVERTER_RESOLUTION = 16
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
input reset,
|
input reset,
|
||||||
|
|
||||||
output [DATA_PATH_WIDTH*16-1:0] pn7_data,
|
output [DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1:0] pn7_data,
|
||||||
output [DATA_PATH_WIDTH*16-1:0] pn15_data
|
output [DATA_PATH_WIDTH*CONVERTER_RESOLUTION-1:0] pn15_data
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam DW = DATA_PATH_WIDTH * 16 - 1;
|
localparam CR = CONVERTER_RESOLUTION;
|
||||||
|
localparam DW = DATA_PATH_WIDTH * CR - 1;
|
||||||
|
|
||||||
reg [DW:0] pn7_state = {DW+1{1'b1}};
|
/* We need at least enough bits to store the PN state */
|
||||||
reg [DW:0] pn15_state = {DW+1{1'b1}};
|
localparam PN7_W = DW > 6 ? DW : 6;
|
||||||
|
localparam PN15_W = DW > 14 ? DW : 14;
|
||||||
|
|
||||||
|
reg [PN7_W:0] pn7_state = {PN7_W+1{1'b1}};
|
||||||
|
reg [PN15_W:0] pn15_state = {PN15_W+1{1'b1}};
|
||||||
|
|
||||||
wire [DW:0] pn7;
|
wire [DW:0] pn7;
|
||||||
wire [DW+7:0] pn7_full_state;
|
wire [DW+7:0] pn7_full_state;
|
||||||
wire [DW:0] pn7_reset;
|
wire [PN7_W:0] pn7_reset;
|
||||||
|
|
||||||
wire [DW:0] pn15;
|
wire [DW:0] pn15;
|
||||||
wire [DW+15:0] pn15_full_state;
|
wire [DW+15:0] pn15_full_state;
|
||||||
wire [DW:0] pn15_reset;
|
wire [PN15_W:0] pn15_reset;
|
||||||
|
|
||||||
/* PN7 x^7 + x^6 + 1 */
|
/* PN7 x^7 + x^6 + 1 */
|
||||||
assign pn7 = pn7_full_state[7+:DW+1] ^ pn7_full_state[6+:DW+1];
|
assign pn7 = pn7_full_state[7+:DW+1] ^ pn7_full_state[6+:DW+1];
|
||||||
|
@ -53,19 +60,26 @@ module ad_ip_jesd204_tpl_dac_pn #(
|
||||||
assign pn15 = pn15_full_state[15+:DW+1] ^ pn15_full_state[14+:DW+1];
|
assign pn15 = pn15_full_state[15+:DW+1] ^ pn15_full_state[14+:DW+1];
|
||||||
assign pn15_full_state = {pn15_state[14:0],pn15};
|
assign pn15_full_state = {pn15_state[14:0],pn15};
|
||||||
|
|
||||||
assign pn7_reset[DW-:7] = {7{1'b1}};
|
assign pn7_reset[PN7_W-:7] = {7{1'b1}};
|
||||||
assign pn7_reset[DW-7:0] = pn7_reset[DW:7] ^ pn7_reset[DW-1:6];
|
assign pn15_reset[PN15_W-:15] = {15{1'b1}};
|
||||||
|
|
||||||
assign pn15_reset[DW-:15] = {15{1'b1}};
|
generate
|
||||||
assign pn15_reset[DW-15:0] = pn15_reset[DW:15] ^ pn15_reset[DW-1:14];
|
if (PN7_W >= 7) begin
|
||||||
|
assign pn7_reset[PN7_W-7:0] = pn7_reset[PN7_W:7] ^ pn7_reset[PN7_W-1:6];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (PN15_W >= 15) begin
|
||||||
|
assign pn15_reset[PN15_W-15:0] = pn15_reset[PN15_W:15] ^ pn15_reset[PN15_W-1:14];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset == 1'b1) begin
|
if (reset == 1'b1) begin
|
||||||
pn7_state <= pn7_reset;
|
pn7_state <= pn7_reset;
|
||||||
pn15_state <= pn15_reset;
|
pn15_state <= pn15_reset;
|
||||||
end else begin
|
end else begin
|
||||||
pn7_state <= pn7;
|
pn7_state <= pn7_full_state[PN7_W:0];
|
||||||
pn15_state <= pn15;
|
pn15_state <= pn15_full_state[PN15_W:0];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,9 +90,9 @@ module ad_ip_jesd204_tpl_dac_pn #(
|
||||||
* sample of the PN state and put it into the LSB sample of the output data.
|
* sample of the PN state and put it into the LSB sample of the output data.
|
||||||
*/
|
*/
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i = 0; i <= DW; i = i + 16) begin: g_pn_swizzle
|
for (i = 0; i <= DW; i = i + CR) begin: g_pn_swizzle
|
||||||
assign pn7_data[i+:16] = pn7_state[DW-i-:16];
|
assign pn7_data[i+:CR] = pn7_state[PN7_W-i-:CR];
|
||||||
assign pn15_data[i+:16] = pn15_state[DW-i-:16];
|
assign pn15_data[i+:CR] = pn15_state[PN15_W-i-:CR];
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue