library: Add a generic JESD204 DAC receiver core

For most of the DACs that use JESD204 as the data transport the digital
interface is very similar. They are mainly differentiated by number of
JESD204 lanes, number of converter channels and number of bits per sample.

Currently for each supported converter there exists a converter specific
core which has the converter specific requirements hard-coded.

Introduce a new generic core that has the number of lanes, number of
channels and bits per sample as synthesis-time configurable parameters. It
can be used as a drop-in replacement for the existing converter specific
cores.

This has the advantage of a shared and reduced code base. Code improvements
will automatically be available for all converters and don't have to be
manually ported to each core individually.

It also makes it very easy to introduce support for new converters that
follow the existing schema.

Since the JESD204 framer is now procedurally generated it is also very
easy to support board or application specific requirements where the lane
to converter ratio differs from the default (E.g. use 2 lanes/2 converters
instead of 4 lanes/2 converters).

This new core is primarily based on the existing axi_ad9144.

For the time being the core is not user instantiatable and will only be
used as a based to re-implement the converter specific cores. It will be
extended in the future to allow user instantiation.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2017-05-05 18:54:09 +02:00 committed by Lars-Peter Clausen
parent b19d09e678
commit e4c9c8734c
9 changed files with 1005 additions and 0 deletions

View File

@ -68,6 +68,7 @@ clean:
$(MAKE) -C cn0363/cn0363_phase_data_sync clean
$(MAKE) -C cordic_demod clean
$(MAKE) -C jesd204/ad_ip_jesd204_tpl_adc clean
$(MAKE) -C jesd204/ad_ip_jesd204_tpl_dac clean
$(MAKE) -C jesd204/axi_jesd204_common clean
$(MAKE) -C jesd204/axi_jesd204_rx clean
$(MAKE) -C jesd204/axi_jesd204_tx clean
@ -175,6 +176,7 @@ lib:
$(MAKE) -C cn0363/cn0363_phase_data_sync
$(MAKE) -C cordic_demod
$(MAKE) -C jesd204/ad_ip_jesd204_tpl_adc
$(MAKE) -C jesd204/ad_ip_jesd204_tpl_dac
$(MAKE) -C jesd204/axi_jesd204_common
$(MAKE) -C jesd204/axi_jesd204_rx
$(MAKE) -C jesd204/axi_jesd204_tx

View File

@ -0,0 +1,43 @@
####################################################################################
## Copyright 2018(c) Analog Devices, Inc.
## Auto-generated, do not modify!
####################################################################################
LIBRARY_NAME := ad_ip_jesd204_tpl_dac
GENERIC_DEPS += ../../common/ad_dds.v
GENERIC_DEPS += ../../common/ad_dds_1.v
GENERIC_DEPS += ../../common/ad_dds_sine.v
GENERIC_DEPS += ../../common/ad_rst.v
GENERIC_DEPS += ../../common/up_axi.v
GENERIC_DEPS += ../../common/up_clock_mon.v
GENERIC_DEPS += ../../common/up_dac_channel.v
GENERIC_DEPS += ../../common/up_dac_common.v
GENERIC_DEPS += ../../common/up_xfer_cntrl.v
GENERIC_DEPS += ../../common/up_xfer_status.v
XILINX_DEPS += ../../xilinx/common/ad_mul.v
XILINX_DEPS += ../../xilinx/common/ad_rst_constr.xdc
XILINX_DEPS += ../../xilinx/common/up_clock_mon_constr.xdc
XILINX_DEPS += ../../xilinx/common/up_xfer_cntrl_constr.xdc
XILINX_DEPS += ../../xilinx/common/up_xfer_status_constr.xdc
XILINX_DEPS += ad_ip_jesd204_tpl_dac.v
XILINX_DEPS += ad_ip_jesd204_tpl_dac_channel.v
XILINX_DEPS += ad_ip_jesd204_tpl_dac_core.v
XILINX_DEPS += ad_ip_jesd204_tpl_dac_framer.v
XILINX_DEPS += ad_ip_jesd204_tpl_dac_ip.tcl
XILINX_DEPS += ad_ip_jesd204_tpl_dac_regmap.v
ALTERA_DEPS += ../../ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac.v
ALTERA_DEPS += ../../ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v
ALTERA_DEPS += ../../ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v
ALTERA_DEPS += ../../ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_framer.v
ALTERA_DEPS += ../../ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v
ALTERA_DEPS += ../../altera/common/ad_mul.v
ALTERA_DEPS += ../../altera/common/up_clock_mon_constr.sdc
ALTERA_DEPS += ../../altera/common/up_rst_constr.sdc
ALTERA_DEPS += ../../altera/common/up_xfer_cntrl_constr.sdc
ALTERA_DEPS += ../../altera/common/up_xfer_status_constr.sdc
ALTERA_DEPS += ad_ip_jesd204_tpl_dac_hw.tcl
include ../../scripts/library.mk

View File

@ -0,0 +1,176 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// Each core or library found in this collection may have its own licensing terms.
// The user should keep this in in mind while exploring these cores.
//
// Redistribution and use in source and binary forms,
// with or without modification of this file, are permitted under the terms of either
// (at the option of the user):
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory, or at:
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
//
// OR
//
// 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_ip_jesd204_tpl_dac #(
parameter ID = 0,
parameter NUM_LANES = 4,
parameter NUM_CHANNELS = 2,
parameter CHANNEL_WIDTH = 16,
parameter DAC_DATAPATH_DISABLE = 0
) (
// jesd interface
// link_clk is (line-rate/40)
input link_clk,
output link_valid,
input link_ready,
output [NUM_LANES*32-1:0] link_data,
// dma interface
output [NUM_CHANNELS-1:0] enable,
output [NUM_CHANNELS-1:0] dac_valid,
input [NUM_LANES*32-1:0] dac_ddata,
input dac_dunf,
// axi interface
input s_axi_aclk,
input s_axi_aresetn,
input s_axi_awvalid,
output s_axi_awready,
input [15:0] s_axi_awaddr,
input [2:0] s_axi_awprot,
input s_axi_wvalid,
output s_axi_wready,
input [31:0] s_axi_wdata,
input [3:0] s_axi_wstrb,
output s_axi_bvalid,
input s_axi_bready,
output [1:0] s_axi_bresp,
input s_axi_arvalid,
output s_axi_arready,
input [15:0] s_axi_araddr,
input [2:0] s_axi_arprot,
output s_axi_rvalid,
input s_axi_rready,
output [31:0] s_axi_rdata,
output [1:0] s_axi_rresp
);
localparam DATA_PATH_WIDTH = 2 * NUM_LANES / NUM_CHANNELS;
// internal signals
wire dac_sync;
wire dac_dds_format;
wire [NUM_CHANNELS*16-1:0] dac_dds_scale_0_s;
wire [NUM_CHANNELS*16-1:0] dac_dds_init_0_s;
wire [NUM_CHANNELS*16-1:0] dac_dds_incr_0_s;
wire [NUM_CHANNELS*16-1:0] dac_dds_scale_1_s;
wire [NUM_CHANNELS*16-1:0] dac_dds_init_1_s;
wire [NUM_CHANNELS*16-1:0] dac_dds_incr_1_s;
wire [NUM_CHANNELS*16-1:0] dac_pat_data_0_s;
wire [NUM_CHANNELS*16-1:0] dac_pat_data_1_s;
wire [NUM_CHANNELS*4-1:0] dac_data_sel_s;
// regmap
ad_ip_jesd204_tpl_dac_regmap #(
.ID (ID),
.NUM_CHANNELS (NUM_CHANNELS),
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
) i_regmap (
.s_axi_aclk (s_axi_aclk),
.s_axi_aresetn (s_axi_aresetn),
.s_axi_awvalid (s_axi_awvalid),
.s_axi_awready (s_axi_awready),
.s_axi_awaddr (s_axi_awaddr),
.s_axi_awprot (s_axi_awprot),
.s_axi_wvalid (s_axi_wvalid),
.s_axi_wready (s_axi_wready),
.s_axi_wdata (s_axi_wdata),
.s_axi_wstrb (s_axi_wstrb),
.s_axi_bvalid (s_axi_bvalid),
.s_axi_bready (s_axi_bready),
.s_axi_bresp (s_axi_bresp),
.s_axi_arvalid (s_axi_arvalid),
.s_axi_arready (s_axi_arready),
.s_axi_araddr (s_axi_araddr),
.s_axi_arprot (s_axi_arprot),
.s_axi_rvalid (s_axi_rvalid),
.s_axi_rresp (s_axi_rresp),
.s_axi_rdata (s_axi_rdata),
.s_axi_rready (s_axi_rready),
.link_clk (link_clk),
.dac_dunf (dac_dunf),
.dac_sync (dac_sync),
.dac_dds_format (dac_dds_format),
.dac_dds_scale_0 (dac_dds_scale_0_s),
.dac_dds_init_0 (dac_dds_init_0_s),
.dac_dds_incr_0 (dac_dds_incr_0_s),
.dac_dds_scale_1 (dac_dds_scale_1_s),
.dac_dds_init_1 (dac_dds_init_1_s),
.dac_dds_incr_1 (dac_dds_incr_1_s),
.dac_pat_data_0 (dac_pat_data_0_s),
.dac_pat_data_1 (dac_pat_data_1_s),
.dac_data_sel (dac_data_sel_s)
);
// core
ad_ip_jesd204_tpl_dac_core #(
.DATAPATH_DISABLE (DAC_DATAPATH_DISABLE),
.NUM_LANES (NUM_LANES),
.NUM_CHANNELS (NUM_CHANNELS),
.DATA_PATH_WIDTH (DATA_PATH_WIDTH)
) i_core (
.clk (link_clk),
.link_valid (link_valid),
.link_ready (link_ready),
.link_data (link_data),
.enable (enable),
.dac_valid (dac_valid),
.dac_ddata (dac_ddata),
.dac_sync (dac_sync),
.dac_dds_format (dac_dds_format),
.dac_dds_scale_0 (dac_dds_scale_0_s),
.dac_dds_init_0 (dac_dds_init_0_s),
.dac_dds_incr_0 (dac_dds_incr_0_s),
.dac_dds_scale_1 (dac_dds_scale_1_s),
.dac_dds_init_1 (dac_dds_init_1_s),
.dac_dds_incr_1 (dac_dds_incr_1_s),
.dac_pat_data_0 (dac_pat_data_0_s),
.dac_pat_data_1 (dac_pat_data_1_s),
.dac_data_sel (dac_data_sel_s)
);
endmodule

View File

@ -0,0 +1,178 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// Each core or library found in this collection may have its own licensing terms.
// The user should keep this in in mind while exploring these cores.
//
// Redistribution and use in source and binary forms,
// with or without modification of this file, are permitted under the terms of either
// (at the option of the user):
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory, or at:
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
//
// OR
//
// 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_ip_jesd204_tpl_dac_channel #(
parameter DATAPATH_DISABLE = 0,
parameter DATA_PATH_WIDTH = 4
) (
// dac interface
input clk,
input [DATA_PATH_WIDTH*16-1:0] dma_data,
output reg [DATA_PATH_WIDTH*16-1:0] dac_data = 'h00,
// Configuration
input dac_data_sync,
input dac_dds_format,
input [3:0] dac_data_sel,
input [15:0] dac_dds_scale_0,
input [15:0] dac_dds_init_0,
input [15:0] dac_dds_incr_0,
input [15:0] dac_dds_scale_1,
input [15:0] dac_dds_init_1,
input [15:0] dac_dds_incr_1,
input [15:0] dac_pat_data_0,
input [15:0] dac_pat_data_1,
output reg dac_enable = 1'b0
);
localparam DW = DATA_PATH_WIDTH * 16 - 1;
// internal registers
reg [DW:0] dac_pn7_data = 'd0;
reg [DW:0] dac_pn15_data = 'd0;
reg [15:0] dac_dds_phase_0[0:DATA_PATH_WIDTH-1];
reg [15:0] dac_dds_phase_1[0:DATA_PATH_WIDTH-1];
reg [DW:0] dac_dds_data = 'd0;
// internal signals
wire [DW:0] dac_dds_data_s;
wire [DW:0] pn15;
wire [DW+15:0] pn15_full_state;
wire [DW:0] dac_pn15_data_s;
wire [DW:0] pn7;
wire [DW+7:0] pn7_full_state;
wire [DW:0] dac_pn7_data_s;
// PN15 x^15 + x^14 + 1
assign pn15 = pn15_full_state[15+:DW+1] ^ pn15_full_state[14+:DW+1];
assign pn15_full_state = {dac_pn15_data[14:0],pn15};
// PN7 x^7 + x^6 + 1
assign pn7 = pn7_full_state[7+:DW+1] ^ pn7_full_state[6+:DW+1];
assign pn7_full_state = {dac_pn7_data[6:0],pn7};
generate
genvar i;
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_pn_swizzle
localparam src_lsb = i * 16;
localparam dst_lsb = (DATA_PATH_WIDTH - i - 1) * 16;
assign dac_pn15_data_s[dst_lsb+:16] = dac_pn15_data[src_lsb+:16];
assign dac_pn7_data_s[dst_lsb+:16] = dac_pn7_data[src_lsb+:16];
end
endgenerate
// dac data select
always @(posedge clk) begin
dac_enable <= (dac_data_sel == 4'h2) ? 1'b1 : 1'b0;
case (dac_data_sel)
4'h7: dac_data <= dac_pn15_data_s;
4'h6: dac_data <= dac_pn7_data_s;
4'h5: dac_data <= ~dac_pn15_data_s;
4'h4: dac_data <= ~dac_pn7_data_s;
4'h3: dac_data <= 'h00;
4'h2: dac_data <= dma_data;
4'h1: dac_data <= {DATA_PATH_WIDTH/2{dac_pat_data_1, dac_pat_data_0}};
default: dac_data <= dac_dds_data;
endcase
end
// pn registers
always @(posedge clk) begin
if (dac_data_sync == 1'b1) begin
dac_pn15_data <= {DW+1{1'd1}};
dac_pn7_data <= {DW+1{1'd1}};
end else begin
dac_pn15_data <= pn15;
dac_pn7_data <= pn7;
end
end
// dds
generate
if (DATAPATH_DISABLE == 1) begin
always @(posedge clk) begin
dac_dds_data <= 64'd0;
end
end else begin
genvar i;
always @(posedge clk) begin
if (dac_data_sync == 1'b1) begin
dac_dds_data <= 64'd0;
end else begin
dac_dds_data <= dac_dds_data_s;
end
end
for (i = 0; i < DATA_PATH_WIDTH; i = i + 1) begin: g_dds_phase
reg [15:0] dac_dds_incr_0_r = 'd0;
reg [15:0] dac_dds_incr_1_r = 'd0;
always @(posedge clk) begin
if (dac_data_sync == 1'b1) begin
dac_dds_incr_0_r <= dac_dds_incr_0 * DATA_PATH_WIDTH;
dac_dds_incr_1_r <= dac_dds_incr_1 * DATA_PATH_WIDTH;
if (i == 0) begin
dac_dds_phase_0[i] <= dac_dds_init_0;
dac_dds_phase_1[i] <= dac_dds_init_1;
end else begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + dac_dds_incr_0;
dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + dac_dds_incr_1;
end
end else begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0_r;
dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1_r;
end
end
ad_dds i_dds (
.clk (clk),
.dds_format (dac_dds_format),
.dds_phase_0 (dac_dds_phase_0[i]),
.dds_scale_0 (dac_dds_scale_0),
.dds_phase_1 (dac_dds_phase_1[i]),
.dds_scale_1 (dac_dds_scale_1),
.dds_data (dac_dds_data_s[16*i+:16])
);
end
end
endgenerate
endmodule

View File

@ -0,0 +1,114 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// Each core or library found in this collection may have its own licensing terms.
// The user should keep this in in mind while exploring these cores.
//
// Redistribution and use in source and binary forms,
// with or without modification of this file, are permitted under the terms of either
// (at the option of the user):
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory, or at:
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
//
// OR
//
// 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_ip_jesd204_tpl_dac_core #(
parameter DATAPATH_DISABLE = 0,
parameter NUM_LANES = 1,
parameter NUM_CHANNELS = 1,
parameter DATA_PATH_WIDTH = 4
) (
// dac interface
input clk,
output link_valid,
input link_ready,
output [NUM_LANES*32-1:0] link_data,
// dma interface
output [NUM_CHANNELS-1:0] dac_valid,
input [NUM_LANES*32-1:0] dac_ddata,
// Configuration interface
input dac_sync,
input dac_dds_format,
input [NUM_CHANNELS*4-1:0] dac_data_sel,
input [NUM_CHANNELS*16-1:0] dac_dds_scale_0,
input [NUM_CHANNELS*16-1:0] dac_dds_init_0,
input [NUM_CHANNELS*16-1:0] dac_dds_incr_0,
input [NUM_CHANNELS*16-1:0] dac_dds_scale_1,
input [NUM_CHANNELS*16-1:0] dac_dds_init_1,
input [NUM_CHANNELS*16-1:0] dac_dds_incr_1,
input [NUM_CHANNELS*16-1:0] dac_pat_data_0,
input [NUM_CHANNELS*16-1:0] dac_pat_data_1,
output [NUM_CHANNELS-1:0] enable
);
assign link_valid = 1'b1;
wire [NUM_LANES*32-1:0] dac_data_s;
// device interface
ad_ip_jesd204_tpl_dac_framer #(
.NUM_LANES (NUM_LANES),
.NUM_CHANNELS (NUM_CHANNELS)
) i_framer (
.clk (clk),
.link_data (link_data),
.dac_data (dac_data_s)
);
// dac valid
assign dac_valid = {NUM_CHANNELS{1'b1}};
localparam CDW = DATA_PATH_WIDTH * 16;
generate
genvar i;
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_channel
ad_ip_jesd204_tpl_dac_channel #(
.DATA_PATH_WIDTH (DATA_PATH_WIDTH),
.DATAPATH_DISABLE (DATAPATH_DISABLE)
) i_channel (
.clk (clk),
.dac_enable (enable[i]),
.dac_data (dac_data_s[CDW*i+:CDW]),
.dma_data (dac_ddata[CDW*i+:CDW]),
.dac_data_sync (dac_sync),
.dac_dds_format (dac_dds_format),
.dac_data_sel (dac_data_sel[4*i+:4]),
.dac_dds_scale_0 (dac_dds_scale_0[16*i+:16]),
.dac_dds_init_0 (dac_dds_init_0[16*i+:16]),
.dac_dds_incr_0 (dac_dds_incr_0[16*i+:16]),
.dac_dds_scale_1 (dac_dds_scale_1[16*i+:16]),
.dac_dds_init_1 (dac_dds_init_1[16*i+:16]),
.dac_dds_incr_1 (dac_dds_incr_1[16*i+:16]),
.dac_pat_data_0 (dac_pat_data_0[16*i+:16]),
.dac_pat_data_1 (dac_pat_data_1[16*i+:16])
);
end
endgenerate
endmodule

View File

@ -0,0 +1,73 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// Each core or library found in this collection may have its own licensing terms.
// The user should keep this in in mind while exploring these cores.
//
// Redistribution and use in source and binary forms,
// with or without modification of this file, are permitted under the terms of either
// (at the option of the user):
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory, or at:
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
//
// OR
//
// 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_ip_jesd204_tpl_dac_framer #(
parameter NUM_LANES = 8,
parameter NUM_CHANNELS = 4
) (
// jesd interface
// clk is (line-rate/40)
input clk,
output [NUM_LANES*32-1:0] link_data,
// dac interface
input [NUM_LANES*32-1:0] dac_data
);
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;
// internal registers
reg [NUM_LANES*32-1:0] link_data_r = 'd0;
wire [NUM_LANES*32-1:0] link_data_s;
always @(posedge clk) begin
link_data_r <= link_data_s;
end
assign link_data = link_data_r;
generate
genvar i;
genvar j;
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_framer_outer
for (j = 0; j < DATA_PATH_WIDTH; j = j + 1) begin: g_framer_inner
localparam k = j + i * DATA_PATH_WIDTH;
localparam dac_lsb = k * 16;
localparam oct0_lsb = HD ? ((i * H + j % H) * 64 + (j / H) * 8) : (k * 16);
localparam oct1_lsb = oct0_lsb + OCT_OFFSET;
assign link_data_s[oct0_lsb+:8] = dac_data[dac_lsb+8+:8];
assign link_data_s[oct1_lsb+:8] = dac_data[dac_lsb+:8];
end
end
endgenerate
endmodule

View File

@ -0,0 +1,104 @@
# ***************************************************************************
# ***************************************************************************
# Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
#
# Each core or library found in this collection may have its own licensing terms.
# The user should keep this in in mind while exploring these cores.
#
# Redistribution and use in source and binary forms,
# with or without modification of this file, are permitted under the terms of either
# (at the option of the user):
#
# 1. The GNU General Public License version 2 as published by the
# Free Software Foundation, which can be found in the top level directory, or at:
# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
#
# OR
#
# 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
#
# ***************************************************************************
# ***************************************************************************
package require qsys
source ../../scripts/adi_env.tcl
source ../../scripts/adi_ip_alt.tcl
ad_ip_create ad_ip_jesd204_tpl_dac {ADI JESD204 Transport DAC Layer} p_ad_ip_jesd204_tpl_dac_elab
ad_ip_files ad_ip_jesd204_tpl_dac [list \
$ad_hdl_dir/library/altera/common/ad_mul.v \
$ad_hdl_dir/library/common/ad_dds_sine.v \
$ad_hdl_dir/library/common/ad_dds_1.v \
$ad_hdl_dir/library/common/ad_dds.v \
$ad_hdl_dir/library/common/ad_rst.v \
$ad_hdl_dir/library/common/up_axi.v \
$ad_hdl_dir/library/common/up_xfer_cntrl.v \
$ad_hdl_dir/library/common/up_xfer_status.v \
$ad_hdl_dir/library/common/up_clock_mon.v \
$ad_hdl_dir/library/common/up_dac_common.v \
$ad_hdl_dir/library/common/up_dac_channel.v \
\
$ad_hdl_dir/library/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac.v \
$ad_hdl_dir/library/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_channel.v \
$ad_hdl_dir/library/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_core.v \
$ad_hdl_dir/library/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_framer.v \
$ad_hdl_dir/library/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v \
\
$ad_hdl_dir/library/altera/common/up_xfer_cntrl_constr.sdc \
$ad_hdl_dir/library/altera/common/up_xfer_status_constr.sdc \
$ad_hdl_dir/library/altera/common/up_clock_mon_constr.sdc \
$ad_hdl_dir/library/altera/common/up_rst_constr.sdc \
]
# 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
# axi4 slave
ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn
# core clock and start of frame
add_interface link_clk clock end
add_interface_port link_clk link_clk clk Input 1
# elaborate
proc p_ad_ip_jesd204_tpl_dac_elab {} {
# read core parameters
set m_num_of_lanes [get_parameter_value "NUM_LANES"]
set m_num_of_channels [get_parameter_value "NUM_CHANNELS"]
set channel_bus_witdh [expr 32*$m_num_of_lanes/$m_num_of_channels]
# link layer interface
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_valid valid output 1
add_interface_port link_data link_ready ready input 1
set_interface_property link_data associatedClock link_clk
set_interface_property link_data dataBitsPerSymbol [expr 32*$m_num_of_lanes]
# dma interface
for {set i 0} {$i < $m_num_of_channels} {incr i} {
add_interface dac_ch_$i conduit end
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]
add_interface_port dac_ch_$i dac_valid_$i valid output 1
set_port_property dac_valid_$i fragment_list [format "dac_valid(%d:%d)" $i $i]
add_interface_port dac_ch_$i dac_data_$i data input $channel_bus_witdh
set_port_property dac_data_$i fragment_list \
[format "dac_ddata(%d:%d)" [expr $channel_bus_witdh*$i+$channel_bus_witdh-1] [expr $channel_bus_witdh*$i]]
set_interface_property dac_ch_$i associatedClock link_clk
}
ad_alt_intf signal dac_dunf input 1 unf
}

View File

@ -0,0 +1,52 @@
# ***************************************************************************
# ***************************************************************************
# Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
#
# Each core or library found in this collection may have its own licensing terms.
# The user should keep this in in mind while exploring these cores.
#
# Redistribution and use in source and binary forms,
# with or without modification of this file, are permitted under the terms of either
# (at the option of the user):
#
# 1. The GNU General Public License version 2 as published by the
# Free Software Foundation, which can be found in the top level directory, or at:
# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
#
# OR
#
# 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
#
# ***************************************************************************
# ***************************************************************************
source ../../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip.tcl
adi_ip_create ad_ip_jesd204_tpl_dac
adi_ip_files ad_ip_jesd204_tpl_dac [list \
"$ad_hdl_dir/library/xilinx/common/ad_mul.v" \
"$ad_hdl_dir/library/common/ad_dds_sine.v" \
"$ad_hdl_dir/library/common/ad_dds_1.v" \
"$ad_hdl_dir/library/common/ad_dds.v" \
"$ad_hdl_dir/library/common/ad_rst.v" \
"$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/common/up_xfer_cntrl.v" \
"$ad_hdl_dir/library/common/up_xfer_status.v" \
"$ad_hdl_dir/library/common/up_clock_mon.v" \
"$ad_hdl_dir/library/common/up_dac_common.v" \
"$ad_hdl_dir/library/common/up_dac_channel.v" \
"$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/up_xfer_status_constr.xdc" \
"$ad_hdl_dir/library/xilinx/common/up_clock_mon_constr.xdc" \
"ad_ip_jesd204_tpl_dac_channel.v" \
"ad_ip_jesd204_tpl_dac_core.v" \
"ad_ip_jesd204_tpl_dac_framer.v" \
"ad_ip_jesd204_tpl_dac_regmap.v" \
"ad_ip_jesd204_tpl_dac.v" ]
adi_ip_properties ad_ip_jesd204_tpl_dac
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,263 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2018 (c) Analog Devices, Inc. All rights reserved.
//
// Each core or library found in this collection may have its own licensing terms.
// The user should keep this in in mind while exploring these cores.
//
// Redistribution and use in source and binary forms,
// with or without modification of this file, are permitted under the terms of either
// (at the option of the user):
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory, or at:
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
//
// OR
//
// 2. An ADI specific BSD license as noted in the top level directory, or on-line at:
// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE
//
// ***************************************************************************
// ***************************************************************************
module ad_ip_jesd204_tpl_dac_regmap #(
parameter ID = 0,
parameter NUM_CHANNELS = 2,
parameter DATA_PATH_WIDTH = 16
) (
input s_axi_aclk,
input s_axi_aresetn,
input s_axi_awvalid,
output s_axi_awready,
input [15:0] s_axi_awaddr,
input [2:0] s_axi_awprot,
input s_axi_wvalid,
output s_axi_wready,
input [31:0] s_axi_wdata,
input [3:0] s_axi_wstrb,
input s_axi_arvalid,
output s_axi_arready,
input [15:0] s_axi_araddr,
input [2:0] s_axi_arprot,
output s_axi_rvalid,
input s_axi_rready,
output [31:0] s_axi_rdata,
output [1:0] s_axi_rresp,
output s_axi_bvalid,
input s_axi_bready,
output [1:0] s_axi_bresp,
input link_clk,
input dac_dunf,
output dac_sync,
output [NUM_CHANNELS*4-1:0] dac_data_sel,
output dac_dds_format,
output [NUM_CHANNELS*16-1:0] dac_dds_scale_0,
output [NUM_CHANNELS*16-1:0] dac_dds_init_0,
output [NUM_CHANNELS*16-1:0] dac_dds_incr_0,
output [NUM_CHANNELS*16-1:0] dac_dds_scale_1,
output [NUM_CHANNELS*16-1:0] dac_dds_init_1,
output [NUM_CHANNELS*16-1:0] dac_dds_incr_1,
output [NUM_CHANNELS*16-1:0] dac_pat_data_0,
output [NUM_CHANNELS*16-1:0] dac_pat_data_1
);
// internal registers
reg up_wack = 1'b0;
reg up_rack = 1'b0;
reg [31:0] up_rdata = 32'h00;
reg [31:0] up_rdata_all;
wire up_wreq_s;
wire [13:0] up_waddr_s;
wire [31:0] up_wdata_s;
wire [NUM_CHANNELS:0] up_wack_s;
wire up_rreq_s;
wire [13:0] up_raddr_s;
wire [31:0] up_rdata_s[0:NUM_CHANNELS];
wire [NUM_CHANNELS:0] up_rack_s;
// internal clocks and resets
wire up_clk;
wire up_rstn;
wire dac_rst;
// signal name changes
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
// up bus interface
up_axi #(
.AXI_ADDRESS_WIDTH (16)
) i_up_axi (
.up_clk (up_clk),
.up_rstn (up_rstn),
.up_axi_awvalid (s_axi_awvalid),
.up_axi_awaddr (s_axi_awaddr),
.up_axi_awready (s_axi_awready),
.up_axi_wvalid (s_axi_wvalid),
.up_axi_wdata (s_axi_wdata),
.up_axi_wstrb (s_axi_wstrb),
.up_axi_wready (s_axi_wready),
.up_axi_bvalid (s_axi_bvalid),
.up_axi_bresp (s_axi_bresp),
.up_axi_bready (s_axi_bready),
.up_axi_arvalid (s_axi_arvalid),
.up_axi_araddr (s_axi_araddr),
.up_axi_arready (s_axi_arready),
.up_axi_rvalid (s_axi_rvalid),
.up_axi_rresp (s_axi_rresp),
.up_axi_rdata (s_axi_rdata),
.up_axi_rready (s_axi_rready),
.up_wreq (up_wreq_s),
.up_waddr (up_waddr_s),
.up_wdata (up_wdata_s),
.up_wack (up_wack),
.up_rreq (up_rreq_s),
.up_raddr (up_raddr_s),
.up_rdata (up_rdata),
.up_rack (up_rack)
);
integer n;
always @(*) begin
up_rdata_all = 'h00;
for (n = 0; n < NUM_CHANNELS + 1; n = n + 1) begin
up_rdata_all = up_rdata_all | up_rdata_s[n];
end
end
always @(posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_rdata <= 'd0;
up_rack <= 'd0;
up_wack <= 'd0;
end else begin
up_rdata <= up_rdata_all;
up_rack <= |up_rack_s;
up_wack <= |up_wack_s;
end
end
// dac common processor interface
up_dac_common #(
.ID (ID),
.DRP_DISABLE (1),
.USERPORTS_DISABLE (1),
.GPIO_DISABLE (1)
) i_up_dac_common (
.mmcm_rst (),
.dac_clk (link_clk),
.dac_rst (dac_rst),
.dac_sync (dac_sync),
.dac_frame (),
.dac_clksel (),
.dac_par_type (),
.dac_par_enb (),
.dac_r1_mode (),
.dac_datafmt (dac_dds_format),
.dac_datarate (),
.dac_status (1'b1),
.dac_status_unf (dac_dunf),
.dac_clk_ratio (DATA_PATH_WIDTH),
.up_drp_sel (),
.up_drp_wr (),
.up_drp_addr (),
.up_drp_wdata (),
.up_drp_rdata (32'd0),
.up_drp_ready (1'd0),
.up_drp_locked (1'd1),
.up_usr_chanmax (),
.dac_usr_chanmax (8'd3),
.up_dac_gpio_in (32'd0),
.up_dac_gpio_out (),
.up_dac_ce (),
.up_pps_rcounter ('h00),
.up_pps_status (1'b0),
.up_pps_irq_mask (),
.up_clk (up_clk),
.up_rstn (up_rstn),
.up_wreq (up_wreq_s),
.up_waddr (up_waddr_s),
.up_wdata (up_wdata_s),
.up_wack (up_wack_s[0]),
.up_rreq (up_rreq_s),
.up_raddr (up_raddr_s),
.up_rdata (up_rdata_s[0]),
.up_rack (up_rack_s[0])
);
generate
genvar i;
for (i = 0; i < NUM_CHANNELS; i = i + 1) begin: g_channel
up_dac_channel #(
.CHANNEL_ID (i),
.USERPORTS_DISABLE (1),
.IQCORRECTION_DISABLE (1)
) i_up_dac_channel (
.dac_clk (link_clk),
.dac_rst (dac_rst),
.dac_dds_scale_1 (dac_dds_scale_0[16*i+:16]),
.dac_dds_init_1 (dac_dds_init_0[16*i+:16]),
.dac_dds_incr_1 (dac_dds_incr_0[16*i+:16]),
.dac_dds_scale_2 (dac_dds_scale_1[16*i+:16]),
.dac_dds_init_2 (dac_dds_init_1[16*i+:16]),
.dac_dds_incr_2 (dac_dds_incr_1[16*i+:16]),
.dac_pat_data_1 (dac_pat_data_0[16*i+:16]),
.dac_pat_data_2 (dac_pat_data_1[16*i+:16]),
.dac_data_sel (dac_data_sel[4*i+:4]),
.dac_iq_mode (),
.dac_iqcor_enb (),
.dac_iqcor_coeff_1 (),
.dac_iqcor_coeff_2 (),
.up_usr_datatype_be (),
.up_usr_datatype_signed (),
.up_usr_datatype_shift (),
.up_usr_datatype_total_bits (),
.up_usr_datatype_bits (),
.up_usr_interpolation_m (),
.up_usr_interpolation_n (),
.dac_usr_datatype_be (1'b0),
.dac_usr_datatype_signed (1'b1),
.dac_usr_datatype_shift (8'd0),
.dac_usr_datatype_total_bits (8'd16),
.dac_usr_datatype_bits (8'd16),
.dac_usr_interpolation_m (16'd1),
.dac_usr_interpolation_n (16'd1),
.up_clk (up_clk),
.up_rstn (up_rstn),
.up_wreq (up_wreq_s),
.up_waddr (up_waddr_s),
.up_wdata (up_wdata_s),
.up_wack (up_wack_s[i+1]),
.up_rreq (up_rreq_s),
.up_raddr (up_raddr_s),
.up_rdata (up_rdata_s[i+1]),
.up_rack (up_rack_s[i+1])
);
end
endgenerate
endmodule