library/axi_ad3552r: Added interface IP for Xilinx projects.
The custom interface IP for AD3552R DAC has more operation capabilities: - 8b register read/write SDR/DDR - 16b register read/write SDR/DDR - data stream SDR/DDR ( clk_in/8 or clk_in/4 update rate) - selectable input source : DMA/ADC/TEST_RAMP - data out clock(SCLK) has clk_in/8 frequency when the converter is configured and clk_in/2 when the converter is in stream mode - the IP reference clock (clk_in) can have a maximum frequency of 132MHz - the IP has multiple device synchronization capability when the DMA is set as an input data source Signed-off-by: PopPaul2021 <Paul.Pop@analog.com>main
parent
86836f5a40
commit
cd33c99b94
|
@ -14,6 +14,7 @@ all: lib
|
|||
|
||||
clean:
|
||||
$(MAKE) -C ad463x_data_capture clean
|
||||
$(MAKE) -C axi_ad3552r clean
|
||||
$(MAKE) -C axi_ad5766 clean
|
||||
$(MAKE) -C axi_ad7606x clean
|
||||
$(MAKE) -C axi_ad7616 clean
|
||||
|
@ -137,6 +138,7 @@ clean-all:clean
|
|||
|
||||
lib:
|
||||
$(MAKE) -C ad463x_data_capture
|
||||
$(MAKE) -C axi_ad3552r
|
||||
$(MAKE) -C axi_ad5766
|
||||
$(MAKE) -C axi_ad7606x
|
||||
$(MAKE) -C axi_ad7616
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
####################################################################################
|
||||
## Copyright (c) 2018 - 2023 Analog Devices, Inc.
|
||||
### SPDX short identifier: BSD-1-Clause
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := axi_ad3552r
|
||||
|
||||
GENERIC_DEPS += ../common/ad_addsub.v
|
||||
GENERIC_DEPS += ../common/ad_dds.v
|
||||
GENERIC_DEPS += ../common/ad_dds_1.v
|
||||
GENERIC_DEPS += ../common/ad_dds_2.v
|
||||
GENERIC_DEPS += ../common/ad_dds_cordic_pipe.v
|
||||
GENERIC_DEPS += ../common/ad_dds_sine.v
|
||||
GENERIC_DEPS += ../common/ad_dds_sine_cordic.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
|
||||
GENERIC_DEPS += axi_ad3552r.v
|
||||
GENERIC_DEPS += axi_ad3552r_channel.v
|
||||
GENERIC_DEPS += axi_ad3552r_core.v
|
||||
GENERIC_DEPS += axi_ad3552r_if.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 += axi_ad3552r_ip.tcl
|
||||
|
||||
include ../scripts/library.mk
|
|
@ -0,0 +1,233 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_ad3552r #(
|
||||
|
||||
parameter ID = 0,
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter FPGA_FAMILY = 0,
|
||||
parameter SPEED_GRADE = 0,
|
||||
parameter DEV_PACKAGE = 0,
|
||||
parameter DDS_DISABLE = 0,
|
||||
parameter DDS_TYPE = 1,
|
||||
parameter DDS_CORDIC_DW = 16,
|
||||
parameter DDS_CORDIC_PHASE_DW = 16
|
||||
) (
|
||||
|
||||
// DAC INTERFACE
|
||||
|
||||
input dac_clk,
|
||||
|
||||
input [31:0] dma_data,
|
||||
input valid_in_dma,
|
||||
input valid_in_dma_sec,
|
||||
output dac_data_ready,
|
||||
|
||||
input [15:0] data_in_a,
|
||||
input [15:0] data_in_b,
|
||||
input valid_in_a,
|
||||
input valid_in_b,
|
||||
|
||||
output dac_sclk,
|
||||
output dac_csn,
|
||||
input [ 3:0] sdio_i,
|
||||
output [ 3:0] sdio_o,
|
||||
output sdio_t,
|
||||
|
||||
// sync transfer between 2 DAC'S
|
||||
|
||||
input external_sync,
|
||||
output sync_ext_device,
|
||||
|
||||
// axi interface
|
||||
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
input s_axi_awvalid,
|
||||
input [15:0] s_axi_awaddr,
|
||||
input [ 2:0] s_axi_awprot,
|
||||
output s_axi_awready,
|
||||
input s_axi_wvalid,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [ 3:0] s_axi_wstrb,
|
||||
output s_axi_wready,
|
||||
output s_axi_bvalid,
|
||||
output [ 1:0] s_axi_bresp,
|
||||
input s_axi_bready,
|
||||
input s_axi_arvalid,
|
||||
input [15:0] s_axi_araddr,
|
||||
input [ 2:0] s_axi_arprot,
|
||||
output s_axi_arready,
|
||||
output s_axi_rvalid,
|
||||
output [ 1:0] s_axi_rresp,
|
||||
output [31:0] s_axi_rdata,
|
||||
input s_axi_rready
|
||||
);
|
||||
|
||||
// internal clocks and resets
|
||||
|
||||
wire dac_rst_s;
|
||||
wire up_clk;
|
||||
wire up_rstn;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire up_wreq_s;
|
||||
wire [13:0] up_waddr_s;
|
||||
wire [31:0] up_wdata_s;
|
||||
wire up_wack_s;
|
||||
wire up_rreq_s;
|
||||
wire [13:0] up_raddr_s;
|
||||
wire [31:0] up_rdata_s;
|
||||
wire up_rack_s;
|
||||
|
||||
wire [ 7:0] address;
|
||||
wire [23:0] data_read;
|
||||
wire [23:0] data_write;
|
||||
wire ddr_sdr_n;
|
||||
wire symb_8_16b;
|
||||
wire transfer_data;
|
||||
wire stream;
|
||||
wire [31:0] dac_data;
|
||||
wire dac_valid;
|
||||
wire if_busy;
|
||||
wire dac_ext_sync_arm;
|
||||
|
||||
// signal name changes
|
||||
|
||||
assign up_clk = s_axi_aclk;
|
||||
assign up_rstn = s_axi_aresetn;
|
||||
|
||||
// device interface
|
||||
axi_ad3552r_if axi_ad3552r_interface (
|
||||
.clk_in(dac_clk),
|
||||
.reset_in(dac_rst_s),
|
||||
.dac_data(dac_data),
|
||||
.dac_data_valid(dac_valid),
|
||||
.dac_data_valid_ext(valid_in_dma_sec),
|
||||
.dac_data_ready(dac_data_ready),
|
||||
.address(address),
|
||||
.data_read(data_read),
|
||||
.data_write(data_write),
|
||||
.sdr_ddr_n(sdr_ddr_n),
|
||||
.symb_8_16b(symb_8_16b),
|
||||
.transfer_data(transfer_data),
|
||||
.stream(stream),
|
||||
.if_busy(if_busy),
|
||||
.external_sync(external_sync),
|
||||
.external_sync_arm(dac_ext_sync_arm),
|
||||
.sync_ext_device(sync_ext_device),
|
||||
.sclk(dac_sclk),
|
||||
.csn(dac_csn),
|
||||
.sdio_i(sdio_i),
|
||||
.sdio_o(sdio_o),
|
||||
.sdio_t(sdio_t));
|
||||
|
||||
// core
|
||||
axi_ad3552r_core #(
|
||||
.ID(ID),
|
||||
.FPGA_TECHNOLOGY(FPGA_TECHNOLOGY),
|
||||
.FPGA_FAMILY(FPGA_FAMILY),
|
||||
.SPEED_GRADE(SPEED_GRADE),
|
||||
.DEV_PACKAGE(DEV_PACKAGE),
|
||||
.DDS_DISABLE(DDS_DISABLE),
|
||||
.DDS_TYPE(DDS_TYPE),
|
||||
.DDS_CORDIC_DW(DDS_CORDIC_DW),
|
||||
.DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW)
|
||||
) axi_ad3552r_up_core (
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst_s),
|
||||
.adc_data_in_a(data_in_a),
|
||||
.adc_data_in_b(data_in_b),
|
||||
.dma_data(dma_data),
|
||||
.adc_valid_in_a(valid_in_a),
|
||||
.adc_valid_in_b(valid_in_b),
|
||||
.valid_in_dma(valid_in_dma),
|
||||
.dac_data_ready(dac_data_ready),
|
||||
.dac_data(dac_data),
|
||||
.dac_valid(dac_valid),
|
||||
.address(address),
|
||||
.data_read(data_read),
|
||||
.data_write(data_write),
|
||||
.sdr_ddr_n(sdr_ddr_n),
|
||||
.symb_8_16b(symb_8_16b),
|
||||
.transfer_data(transfer_data),
|
||||
.stream(stream),
|
||||
.dac_ext_sync_arm(dac_ext_sync_arm),
|
||||
.if_busy(if_busy),
|
||||
.up_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.up_wreq(up_wreq_s),
|
||||
.up_waddr(up_waddr_s),
|
||||
.up_wdata(up_wdata_s),
|
||||
.up_wack(up_wack_s),
|
||||
.up_rreq(up_rreq_s),
|
||||
.up_raddr(up_raddr_s),
|
||||
.up_rdata(up_rdata_s),
|
||||
.up_rack(up_rack_s));
|
||||
|
||||
// up bus interface
|
||||
|
||||
up_axi i_up_axi(
|
||||
.up_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.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_s),
|
||||
.up_rreq(up_rreq_s),
|
||||
.up_raddr(up_raddr_s),
|
||||
.up_rdata(up_rdata_s),
|
||||
.up_rack(up_rack_s));
|
||||
endmodule
|
|
@ -0,0 +1,227 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modificat
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_ad3552r_channel #(
|
||||
|
||||
parameter CHANNEL_ID = 32'h0,
|
||||
parameter DDS_DISABLE = 0,
|
||||
parameter DDS_TYPE = 1,
|
||||
parameter DDS_CORDIC_DW = 16,
|
||||
parameter DDS_CORDIC_PHASE_DW = 16
|
||||
) (
|
||||
|
||||
// dac interface
|
||||
|
||||
input dac_clk,
|
||||
input dac_rst,
|
||||
output dac_data_valid,
|
||||
output [15:0] dac_data,
|
||||
|
||||
// input sources
|
||||
|
||||
input [15:0] dma_data,
|
||||
input [15:0] adc_data,
|
||||
input valid_in_adc,
|
||||
input valid_in_dma,
|
||||
input dac_data_ready,
|
||||
|
||||
// processor interface
|
||||
|
||||
input dac_data_sync,
|
||||
input dac_dfmt_type,
|
||||
|
||||
// bus interface
|
||||
|
||||
input up_rstn,
|
||||
input up_clk,
|
||||
input up_wreq,
|
||||
input [13:0] up_waddr,
|
||||
input [31:0] up_wdata,
|
||||
output up_wack,
|
||||
input up_rreq,
|
||||
input [13:0] up_raddr,
|
||||
output [31:0] up_rdata,
|
||||
output up_rack
|
||||
);
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [15:0] formatted_dma_data;
|
||||
wire [15:0] formatted_adc_data;
|
||||
wire [ 3:0] dac_data_sel_s;
|
||||
|
||||
wire [15:0] dac_dds_data_s;
|
||||
wire [15:0] dac_dds_scale_1_s;
|
||||
wire [15:0] dac_dds_init_1_s;
|
||||
wire [15:0] dac_dds_incr_1_s;
|
||||
wire [15:0] dac_dds_scale_2_s;
|
||||
wire [15:0] dac_dds_init_2_s;
|
||||
wire [15:0] dac_dds_incr_2_s;
|
||||
wire [15:0] dac_pat_data_1_s;
|
||||
wire [15:0] dac_pat_data_2_s;
|
||||
|
||||
reg [15:0] ramp_pattern = 16'h0000;
|
||||
reg ramp_valid = 1'b0;
|
||||
reg [15:0] dac_data_int;
|
||||
reg dac_data_valid_int;
|
||||
|
||||
assign dac_data = dac_data_int;
|
||||
assign dac_data_valid = dac_data_valid_int;
|
||||
|
||||
assign formatted_dma_data [15] = dac_dfmt_type ^ dma_data[15];
|
||||
assign formatted_dma_data [14:0] = dma_data[14:0];
|
||||
assign formatted_adc_data [15] = dac_dfmt_type ^ adc_data[15];
|
||||
assign formatted_adc_data [14:0] = adc_data[14:0];
|
||||
|
||||
always @ (*) begin
|
||||
case(dac_data_sel_s)
|
||||
4'h0 :
|
||||
begin
|
||||
dac_data_int = dac_dds_data_s;
|
||||
dac_data_valid_int = 1'b1;
|
||||
end
|
||||
4'h2 :
|
||||
begin
|
||||
dac_data_int = formatted_dma_data;
|
||||
dac_data_valid_int = valid_in_dma;
|
||||
end
|
||||
4'h3 :
|
||||
begin
|
||||
dac_data_int = 16'b0;
|
||||
dac_data_valid_int = 1'b1;
|
||||
end
|
||||
4'h8 :
|
||||
begin
|
||||
dac_data_int = formatted_adc_data;
|
||||
dac_data_valid_int = valid_in_adc;
|
||||
end
|
||||
4'hb :
|
||||
begin
|
||||
dac_data_int = ramp_pattern;
|
||||
dac_data_valid_int = ramp_valid;
|
||||
end
|
||||
default :
|
||||
begin
|
||||
dac_data_int = 16'b0;
|
||||
dac_data_valid_int = 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// ramp generator
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
ramp_valid <= 1'b1;
|
||||
if(dac_data_ready == 1'b1) begin
|
||||
ramp_pattern <= ramp_pattern + 1'b1;
|
||||
end else begin
|
||||
ramp_pattern <= ramp_pattern;
|
||||
end
|
||||
if(ramp_pattern == 16'hffff || dac_rst == 1'b1) begin
|
||||
ramp_pattern <= 16'h0;
|
||||
end
|
||||
end
|
||||
|
||||
ad_dds #(
|
||||
.DISABLE (DDS_DISABLE),
|
||||
.DDS_DW (16),
|
||||
.PHASE_DW (16),
|
||||
.DDS_TYPE (DDS_TYPE),
|
||||
.CORDIC_DW (DDS_CORDIC_DW),
|
||||
.CORDIC_PHASE_DW (DDS_CORDIC_PHASE_DW),
|
||||
.CLK_RATIO (1)
|
||||
) i_dds (
|
||||
.clk (dac_clk),
|
||||
.dac_dds_format (dac_dfmt_type),
|
||||
.dac_data_sync (dac_data_sync),
|
||||
.dac_valid (dac_data_ready),
|
||||
.tone_1_scale (dac_dds_scale_1_s),
|
||||
.tone_2_scale (dac_dds_scale_2_s),
|
||||
.tone_1_init_offset (dac_dds_init_1_s),
|
||||
.tone_2_init_offset (dac_dds_init_2_s),
|
||||
.tone_1_freq_word (dac_dds_incr_1_s),
|
||||
.tone_2_freq_word (dac_dds_incr_2_s),
|
||||
.dac_dds_data (dac_dds_data_s));
|
||||
|
||||
// single channel processor
|
||||
|
||||
up_dac_channel #(
|
||||
.CHANNEL_ID(CHANNEL_ID),
|
||||
.COMMON_ID(6'h01)
|
||||
) dac_channel (
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst),
|
||||
.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_dds_scale_2(dac_dds_scale_2_s),
|
||||
.dac_dds_init_2(dac_dds_init_2_s),
|
||||
.dac_dds_incr_2(dac_dds_incr_2_s),
|
||||
.dac_pat_data_1(dac_pat_data_1_s),
|
||||
.dac_pat_data_2(dac_pat_data_2_s),
|
||||
.dac_data_sel(dac_data_sel_s),
|
||||
.dac_mask_enable(),
|
||||
.dac_iq_mode(),
|
||||
.dac_iqcor_enb(),
|
||||
.dac_iqcor_coeff_1(),
|
||||
.dac_iqcor_coeff_2(),
|
||||
.dac_src_chan_sel(),
|
||||
.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'd0),
|
||||
.dac_usr_datatype_signed(1'd1),
|
||||
.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_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.up_wreq(up_wreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_wack(up_wack),
|
||||
.up_rreq(up_rreq),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata),
|
||||
.up_rack(up_rack));
|
||||
endmodule
|
|
@ -0,0 +1,261 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_ad3552r_core #(
|
||||
parameter ID = 0,
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter FPGA_FAMILY = 0,
|
||||
parameter SPEED_GRADE = 0,
|
||||
parameter DEV_PACKAGE = 0,
|
||||
parameter DDS_DISABLE = 0,
|
||||
parameter DDS_TYPE = 1,
|
||||
parameter DDS_CORDIC_DW = 16,
|
||||
parameter DDS_CORDIC_PHASE_DW = 16
|
||||
) (
|
||||
|
||||
// dac interface
|
||||
|
||||
input dac_clk,
|
||||
output dac_rst,
|
||||
input [15:0] adc_data_in_a,
|
||||
input [15:0] adc_data_in_b,
|
||||
input [31:0] dma_data,
|
||||
input adc_valid_in_a,
|
||||
input adc_valid_in_b,
|
||||
input valid_in_dma,
|
||||
output [31:0] dac_data,
|
||||
output dac_valid,
|
||||
input dac_data_ready,
|
||||
|
||||
// output
|
||||
|
||||
output [ 7:0] address,
|
||||
input if_busy,
|
||||
input [23:0] data_read,
|
||||
output [23:0] data_write,
|
||||
output sdr_ddr_n,
|
||||
output symb_8_16b,
|
||||
output transfer_data,
|
||||
output stream,
|
||||
output dac_ext_sync_arm,
|
||||
|
||||
// processor interface
|
||||
|
||||
input up_rstn,
|
||||
input up_clk,
|
||||
input up_wreq,
|
||||
input [13:0] up_waddr,
|
||||
input [31:0] up_wdata,
|
||||
output reg up_wack,
|
||||
input up_rreq,
|
||||
input [13:0] up_raddr,
|
||||
output reg [31:0] up_rdata,
|
||||
output reg up_rack
|
||||
);
|
||||
|
||||
wire [31:0] up_rdata_0_s;
|
||||
wire up_rack_0_s;
|
||||
wire up_wack_0_s;
|
||||
wire [31:0] up_rdata_1_s;
|
||||
wire up_rack_1_s;
|
||||
wire up_wack_1_s;
|
||||
wire [31:0] up_rdata_s;
|
||||
wire up_rack_s;
|
||||
wire up_wack_s;
|
||||
|
||||
wire [15:0] dac_data_channel_0;
|
||||
wire [15:0] dac_data_channel_1;
|
||||
wire dac_valid_channel_0;
|
||||
wire dac_valid_channel_1;
|
||||
wire dac_rst_s;
|
||||
|
||||
wire [31:0] dac_data_control;
|
||||
wire [31:0] dac_control;
|
||||
|
||||
wire dac_data_sync;
|
||||
wire dac_dfmt_type;
|
||||
|
||||
// defaults
|
||||
|
||||
assign dac_rst = dac_rst_s;
|
||||
assign dac_data = {dac_data_channel_1 ,dac_data_channel_0};
|
||||
assign dac_valid = dac_valid_channel_0 | dac_valid_channel_1;
|
||||
|
||||
assign data_write = dac_data_control[23:0];
|
||||
assign transfer_data = dac_control[0];
|
||||
assign stream = dac_control[1];
|
||||
assign address = dac_control[31:24];
|
||||
|
||||
// processor read interface
|
||||
|
||||
always @(negedge up_rstn or posedge up_clk) begin
|
||||
if(up_rstn == 0) begin
|
||||
up_rdata <= 'd0;
|
||||
up_rack <= 'd0;
|
||||
up_wack <= 'd0;
|
||||
end else begin
|
||||
up_rdata <= up_rdata_s | up_rdata_0_s | up_rdata_1_s;
|
||||
up_rack <= up_rack_s | up_rack_0_s | up_rack_1_s;
|
||||
up_wack <= up_wack_s | up_wack_0_s | up_wack_1_s;
|
||||
end
|
||||
end
|
||||
|
||||
// DAC CHANNEL 0
|
||||
|
||||
axi_ad3552r_channel #(
|
||||
.CHANNEL_ID(0),
|
||||
.DDS_DISABLE(DDS_DISABLE),
|
||||
.DDS_TYPE(DDS_TYPE),
|
||||
.DDS_CORDIC_DW(DDS_CORDIC_DW),
|
||||
.DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW)
|
||||
) axi_ad3552r_channel_0 (
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst_s),
|
||||
.dac_data_valid(dac_valid_channel_0),
|
||||
.dac_data(dac_data_channel_0),
|
||||
.dma_data(dma_data[15:0]),
|
||||
.dac_data_ready(dac_data_ready),
|
||||
.adc_data(adc_data_in_a),
|
||||
.valid_in_adc(adc_valid_in_a),
|
||||
.valid_in_dma(valid_in_dma),
|
||||
.dac_data_sync(dac_data_sync),
|
||||
.dac_dfmt_type(dac_dfmt_type),
|
||||
.up_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.up_wreq(up_wreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_wack(up_wack_0_s),
|
||||
.up_rreq(up_rreq),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_0_s),
|
||||
.up_rack(up_rack_0_s));
|
||||
|
||||
// DAC CHANNEL 1
|
||||
|
||||
axi_ad3552r_channel #(
|
||||
.CHANNEL_ID(1),
|
||||
.DDS_DISABLE(DDS_DISABLE),
|
||||
.DDS_TYPE(DDS_TYPE),
|
||||
.DDS_CORDIC_DW(DDS_CORDIC_DW),
|
||||
.DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW)
|
||||
) axi_ad3552r_channel_1(
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst_s),
|
||||
.dac_data_valid(dac_valid_channel_1),
|
||||
.dac_data(dac_data_channel_1),
|
||||
.dma_data(dma_data[31:16]),
|
||||
.dac_data_ready(dac_data_ready),
|
||||
.adc_data(adc_data_in_b),
|
||||
.valid_in_adc(adc_valid_in_b),
|
||||
.valid_in_dma(valid_in_dma),
|
||||
.dac_data_sync(dac_data_sync),
|
||||
.dac_dfmt_type(dac_dfmt_type),
|
||||
.up_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.up_wreq(up_wreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_wack(up_wack_1_s),
|
||||
.up_rreq(up_rreq),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_1_s),
|
||||
.up_rack(up_rack_1_s));
|
||||
|
||||
// dac common processor interface
|
||||
|
||||
up_dac_common #(
|
||||
.ID(ID),
|
||||
.FPGA_TECHNOLOGY(FPGA_TECHNOLOGY),
|
||||
.FPGA_FAMILY(FPGA_FAMILY),
|
||||
.SPEED_GRADE(SPEED_GRADE),
|
||||
.DEV_PACKAGE(DEV_PACKAGE),
|
||||
.COMMON_ID(6'h00)
|
||||
) axi_ad3552r_common_core (
|
||||
.mmcm_rst(),
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst_s),
|
||||
.dac_num_lanes(),
|
||||
.dac_sdr_ddr_n(sdr_ddr_n),
|
||||
.dac_symb_op(),
|
||||
.dac_symb_8_16b(symb_8_16b),
|
||||
.dac_sync(dac_data_sync),
|
||||
.dac_ext_sync_arm(dac_ext_sync_arm),
|
||||
.dac_ext_sync_disarm(),
|
||||
.dac_ext_sync_manual_req(),
|
||||
.dac_frame(),
|
||||
.dac_clksel(),
|
||||
.dac_custom_wr(dac_data_control),
|
||||
.dac_custom_rd({8'b0, data_read}),
|
||||
.dac_custom_control(dac_control),
|
||||
.dac_status_if_busy(if_busy),
|
||||
.dac_par_type(),
|
||||
.dac_par_enb(),
|
||||
.dac_r1_mode(),
|
||||
.dac_datafmt(dac_dfmt_type),
|
||||
.dac_datarate(),
|
||||
.dac_status(),
|
||||
.dac_sync_in_status(),
|
||||
.dac_status_unf(),
|
||||
.dac_clk_ratio(32'd1),
|
||||
.up_dac_ce(),
|
||||
.up_pps_rcounter(32'd0),
|
||||
.up_pps_status(1'd0),
|
||||
.up_pps_irq_mask(),
|
||||
.up_dac_r1_mode(),
|
||||
.up_drp_sel(),
|
||||
.up_drp_wr(),
|
||||
.up_drp_addr(),
|
||||
.up_drp_wdata() ,
|
||||
.up_drp_rdata(32'd0),
|
||||
.up_drp_ready(1'd1),
|
||||
.up_drp_locked(1'd1),
|
||||
.up_usr_chanmax(),
|
||||
.dac_usr_chanmax(8'd1),
|
||||
.up_dac_gpio_in(32'd0),
|
||||
.up_dac_gpio_out(),
|
||||
.up_rstn(up_rstn),
|
||||
.up_clk(up_clk),
|
||||
.up_wreq(up_wreq),
|
||||
.up_waddr(up_waddr),
|
||||
.up_wdata(up_wdata),
|
||||
.up_wack(up_wack_s),
|
||||
.up_rreq(up_rreq),
|
||||
.up_raddr(up_raddr),
|
||||
.up_rdata(up_rdata_s),
|
||||
.up_rack (up_rack_s));
|
||||
endmodule
|
|
@ -0,0 +1,316 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_ad3552r_if (
|
||||
|
||||
input clk_in, // 120MHz
|
||||
input reset_in,
|
||||
input [31:0] dac_data,
|
||||
input dac_data_valid,
|
||||
input dac_data_valid_ext,
|
||||
output dac_data_ready,
|
||||
|
||||
input [ 7:0] address,
|
||||
input [23:0] data_write,
|
||||
input sdr_ddr_n,
|
||||
input symb_8_16b,
|
||||
input transfer_data,
|
||||
input stream,
|
||||
input external_sync,
|
||||
input external_sync_arm,
|
||||
|
||||
output if_busy,
|
||||
output sync_ext_device,
|
||||
output reg [23:0] data_read,
|
||||
|
||||
// DAC control signals
|
||||
|
||||
output sclk,
|
||||
output reg csn,
|
||||
input [ 3:0] sdio_i,
|
||||
output [ 3:0] sdio_o,
|
||||
output sdio_t
|
||||
);
|
||||
|
||||
wire transfer_data_s;
|
||||
wire start_synced;
|
||||
wire [31:0] dac_data_int;
|
||||
wire dac_data_valid_synced;
|
||||
wire external_sync_s;
|
||||
|
||||
reg [55:0] transfer_reg = 56'h0;
|
||||
reg [15:0] counter = 16'h0;
|
||||
reg [ 2:0] transfer_state = 0;
|
||||
reg [ 2:0] transfer_state_next = 0;
|
||||
reg cycle_done = 1'b0;
|
||||
reg transfer_step = 1'b0;
|
||||
reg sclk_ddr = 1'b0;
|
||||
reg full_speed = 1'b0;
|
||||
reg transfer_data_d = 1'b0;
|
||||
reg transfer_data_dd = 1'b0;
|
||||
reg [ 3:0] valid_captured_d = 4'b0;
|
||||
reg data_r_wn = 1'b0;
|
||||
reg valid_captured = 1'b0;
|
||||
reg start_transfer = 1'b0;
|
||||
reg if_busy_reg = 1'b0;
|
||||
reg dac_data_ready_s = 1'b0;
|
||||
reg external_sync_arm_reg = 1'b0;
|
||||
reg external_sync_reg = 1'b0;
|
||||
|
||||
localparam [ 2:0] IDLE = 3'h0,
|
||||
CS_LOW = 3'h1,
|
||||
WRITE_ADDRESS = 3'h2,
|
||||
TRANSFER_REGISTER = 3'h3,
|
||||
READ_REGISTER = 3'h4,
|
||||
STREAM = 3'h5,
|
||||
CS_HIGH = 3'h6;
|
||||
|
||||
assign if_busy = if_busy_reg;
|
||||
|
||||
// transform the transfer data rising edge into a pulse
|
||||
|
||||
assign transfer_data_s = transfer_data_d & ~transfer_data_dd;
|
||||
|
||||
// start the data stream transfer after valid has been captured
|
||||
|
||||
assign start_synced = valid_captured_d[1] & start_transfer & stream;
|
||||
assign sync_ext_device = start_synced ;
|
||||
|
||||
// use dac_data valid from an external source only if external_sync_arm_reg is 1
|
||||
|
||||
assign dac_data_valid_synced = (external_sync_arm_reg == 1'b1) ? (dac_data_valid & dac_data_valid_ext) : dac_data_valid ;
|
||||
assign dac_data_ready = dac_data_ready_s & dac_data_valid_synced;
|
||||
assign dac_data_int = dac_data;
|
||||
|
||||
// sync the data only if the synchronizations has been armed in software
|
||||
|
||||
assign external_sync_s = ~external_sync_arm_reg | external_sync_reg;
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if(reset_in == 1'b1) begin
|
||||
transfer_data_d <= 'd0;
|
||||
transfer_data_dd <= 'd0;
|
||||
valid_captured_d <= 4'b0;
|
||||
valid_captured <= 1'b0;
|
||||
end else begin
|
||||
transfer_data_d <= transfer_data;
|
||||
transfer_data_dd <= transfer_data_d;
|
||||
valid_captured_d <= {valid_captured_d[2:0], valid_captured};
|
||||
end
|
||||
if(transfer_state == CS_HIGH || stream == 1'b0) begin
|
||||
start_transfer <= 1'b0;
|
||||
valid_captured <= 1'b0;
|
||||
valid_captured_d <= 4'b0;
|
||||
end
|
||||
|
||||
// pulse to level conversion
|
||||
|
||||
if(external_sync_arm == 1'b1) begin
|
||||
external_sync_arm_reg <= 1'b1;
|
||||
end
|
||||
if(external_sync == 1'b1) begin
|
||||
external_sync_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if(transfer_state == CS_HIGH) begin
|
||||
external_sync_arm_reg <= 1'b0;
|
||||
external_sync_reg <= 1'b0;
|
||||
end
|
||||
|
||||
if(dac_data_valid == 1'b1 && start_transfer == 1'b1) begin
|
||||
valid_captured <= 1'b1;
|
||||
end
|
||||
if(transfer_data == 1'b1) begin
|
||||
start_transfer <= 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (reset_in == 1'b1) begin
|
||||
transfer_state <= IDLE;
|
||||
end else begin
|
||||
transfer_state <= transfer_state_next;
|
||||
end
|
||||
end
|
||||
|
||||
// FSM next state logic
|
||||
|
||||
always @(*) begin
|
||||
case (transfer_state)
|
||||
IDLE : begin
|
||||
// goes in to the next state only if the control is to transfer register or synced transfer(if it's armed in software)
|
||||
transfer_state_next = ((transfer_data_s == 1'b1 && stream == 1'b0) || (start_synced == 1'b1 && external_sync_s)) ? CS_LOW : IDLE;
|
||||
csn = 1'b1;
|
||||
transfer_step = 0;
|
||||
cycle_done = 0;
|
||||
end
|
||||
CS_LOW : begin
|
||||
// brings CS down
|
||||
// loads all configuration
|
||||
// puts data on the SDIO pins
|
||||
// needs 5 ns before risedge of the clock
|
||||
transfer_state_next = WRITE_ADDRESS;
|
||||
csn = 1'b0;
|
||||
transfer_step = 0;
|
||||
cycle_done = 0;
|
||||
end
|
||||
WRITE_ADDRESS : begin
|
||||
// writes the address
|
||||
// it works either at full speed (60 MHz) when streaming or normal
|
||||
// speed (15 MHz)
|
||||
// full speed - 2 clock cycles
|
||||
// half speed 8 clock cycles
|
||||
cycle_done = full_speed ? (counter == 16'h3) : (counter == 16'hf);
|
||||
transfer_state_next = cycle_done ? (stream ? STREAM : TRANSFER_REGISTER) : WRITE_ADDRESS ;
|
||||
csn = 1'b0;
|
||||
// in streaming, change data on falledge. On regular transfer, change data on negedge.
|
||||
//A single step should be done for 8 bit addressing
|
||||
transfer_step = full_speed ? (counter[0]== 1'h1) : ((counter[4:0] == 5'h5));
|
||||
end
|
||||
TRANSFER_REGISTER : begin
|
||||
// always works at 15 MHz
|
||||
// can be DDR or SDR
|
||||
cycle_done = sdr_ddr_n ? (symb_8_16b ? (counter == 16'h10) : (counter == 16'h20)) :
|
||||
(symb_8_16b ? (counter == 16'h09) : (counter == 16'h11));
|
||||
transfer_state_next = cycle_done ? CS_HIGH : TRANSFER_REGISTER;
|
||||
csn = 1'b0;
|
||||
// in DDR mode, change data on falledge
|
||||
transfer_step = sdr_ddr_n ? (counter[2:0] == 3'h0) : (counter[1:0] == 2'h0);
|
||||
end
|
||||
STREAM : begin
|
||||
// can be DDR or SDR
|
||||
// in DDR mode needs to be make sure the clock and data is shifted by 2 ns
|
||||
cycle_done = stream ? (sdr_ddr_n ? (counter == 16'h0f) : (counter == 16'h7)):
|
||||
(sdr_ddr_n ? (counter == 16'h10) : (counter == 16'h7));
|
||||
transfer_state_next = (stream && external_sync_s) ? STREAM: ((cycle_done || external_sync_s == 1'b0) ? CS_HIGH :STREAM);
|
||||
csn = 1'b0;
|
||||
transfer_step = sdr_ddr_n ? counter[0] : 1'b1;
|
||||
end
|
||||
CS_HIGH : begin
|
||||
cycle_done = 1'b1;
|
||||
transfer_state_next = cycle_done ? IDLE : CS_HIGH;
|
||||
csn = 1'b1;
|
||||
transfer_step = 0;
|
||||
end
|
||||
default : begin
|
||||
cycle_done = 0;
|
||||
transfer_state_next = IDLE;
|
||||
csn = 1'b1;
|
||||
transfer_step = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// counter is used to time all states
|
||||
// depends on number of clock cycles per phase
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (transfer_state == IDLE || reset_in == 1'b1) begin
|
||||
counter <= 'b0;
|
||||
end else if (transfer_state == WRITE_ADDRESS | transfer_state == TRANSFER_REGISTER | transfer_state == STREAM) begin
|
||||
if (cycle_done) begin
|
||||
counter <= 0;
|
||||
end else begin
|
||||
counter <= counter + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge clk_in) begin
|
||||
if (transfer_state == STREAM | transfer_state == WRITE_ADDRESS) begin
|
||||
sclk_ddr <= !sclk_ddr;
|
||||
end else begin
|
||||
sclk_ddr <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// selection between 60 MHz and 15 MHz
|
||||
|
||||
assign sclk = full_speed ? (sdr_ddr_n ? counter[0] : sclk_ddr) : counter[2];
|
||||
|
||||
always @(posedge clk_in) begin
|
||||
if (transfer_state == CS_LOW) begin
|
||||
data_r_wn <= address[7];
|
||||
end else if (transfer_state == CS_HIGH) begin
|
||||
data_r_wn <=1'b0;
|
||||
end
|
||||
if (transfer_state == STREAM) begin
|
||||
if (cycle_done == 1'b1) begin
|
||||
dac_data_ready_s <= stream;
|
||||
end else begin
|
||||
dac_data_ready_s <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
dac_data_ready_s <= 1'b0;
|
||||
end
|
||||
if (transfer_state == CS_LOW) begin
|
||||
full_speed = stream;
|
||||
if(stream) begin
|
||||
transfer_reg <= {address,dac_data_int, 16'h0};
|
||||
end else begin
|
||||
transfer_reg <= {address,data_write, 24'h0};
|
||||
end
|
||||
end else if ((transfer_state == STREAM & cycle_done) || (transfer_state != STREAM && transfer_state_next == STREAM)) begin
|
||||
transfer_reg <= {dac_data_int, 24'h0};
|
||||
end else if (transfer_step && transfer_state != CS_HIGH) begin
|
||||
transfer_reg <= {transfer_reg[51:0], sdio_i};
|
||||
end
|
||||
|
||||
if (transfer_state == CS_HIGH) begin
|
||||
if (symb_8_16b == 1'b0) begin
|
||||
data_read <= {8'h0,transfer_reg[15:0]};
|
||||
end else begin
|
||||
data_read <= {16'h0,transfer_reg[7:0]};
|
||||
end
|
||||
end else begin
|
||||
data_read <= data_read;
|
||||
end
|
||||
if (transfer_state == CS_HIGH || transfer_state == IDLE) begin
|
||||
if_busy_reg <= 1'b0;
|
||||
end else begin
|
||||
if_busy_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// address[7] is r_wn : depends also on the state machine, input only when
|
||||
// in TRANSFER register mode
|
||||
|
||||
assign sdio_t = (data_r_wn & transfer_state == TRANSFER_REGISTER);
|
||||
assign sdio_o = transfer_reg[55:52];
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
SOURCE="$0.v"
|
||||
SOURCE+=" axi_ad3552r_if.v"
|
||||
|
||||
cd `dirname $0`
|
||||
source ../common/tb/run_tb.sh
|
|
@ -0,0 +1,239 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_ad3552r_if_tb;
|
||||
parameter VCD_FILE = "axi_ad3552r_if_tb.vcd";
|
||||
|
||||
`define TIMEOUT 9000
|
||||
`include "../common/tb/tb_base.v"
|
||||
|
||||
wire [ 23:0] data_read;
|
||||
wire dac_sclk;
|
||||
wire dac_csn;
|
||||
wire dac_data_ready;
|
||||
wire [ 3:0] sdio_i;
|
||||
wire [ 3:0] sdio_o;
|
||||
wire sdio_t;
|
||||
wire [31:0] dac_data_final;
|
||||
wire [ 3:0] readback_data_shift;
|
||||
wire [ 4:0] data_increment_valid;
|
||||
wire if_busy;
|
||||
|
||||
reg [ 7:0] address_write = 8'b0;
|
||||
reg dac_clk = 1'b0;
|
||||
reg reset_in = 1'b1;
|
||||
reg transfer_data = 1'b0;
|
||||
reg sdr_ddr_n = 1'b1;
|
||||
reg reg_8b_16bn = 1'b0;
|
||||
reg stream = 1'b0;
|
||||
reg [23:0] data_write = 24'h0;
|
||||
reg dac_data_valid = 1'b0;
|
||||
reg [ 3:0] shift_count = 4'b0;
|
||||
reg [31:0] transfer_reg = 32'h89abcdef;
|
||||
reg [ 4:0] valid_counter = 5'b0;
|
||||
reg [31:0] dac_data = 32'b0;
|
||||
|
||||
always #4 dac_clk <= ~dac_clk;
|
||||
|
||||
initial begin
|
||||
|
||||
#100 reset_in = 1'b0;
|
||||
|
||||
// Write 8 bit SDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
data_write = 24'hab0000;
|
||||
sdr_ddr_n = 1'b1;
|
||||
reg_8b_16bn = 1'b1;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Read 8 bit SDR
|
||||
|
||||
address_write = 8'hac;
|
||||
data_write = 24'h000000;
|
||||
sdr_ddr_n = 1'b1;
|
||||
reg_8b_16bn = 1'b1;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Write 16 bit SDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
data_write = 24'h123400;
|
||||
sdr_ddr_n = 1'b1;
|
||||
reg_8b_16bn = 1'b0;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Read 16 bit SDR
|
||||
|
||||
address_write = 8'hac;
|
||||
data_write = 24'h000000;
|
||||
sdr_ddr_n = 1'b1;
|
||||
reg_8b_16bn = 1'b0;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
#500;
|
||||
|
||||
// Write 8 bit DDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
data_write = 24'h120000;
|
||||
sdr_ddr_n = 1'b0;
|
||||
reg_8b_16bn = 1'b1;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Read 8 bit DDR
|
||||
|
||||
address_write = 8'hac;
|
||||
data_write = 24'h000000;
|
||||
sdr_ddr_n = 1'b0;
|
||||
reg_8b_16bn = 1'b1;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Write 16 bit DDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
data_write = 24'h123400;
|
||||
sdr_ddr_n = 1'b0;
|
||||
reg_8b_16bn = 1'b0;
|
||||
stream = 1'b0;
|
||||
transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
// Read 16 bit DDR
|
||||
|
||||
address_write = 8'hac;
|
||||
data_write = 24'h000000;
|
||||
sdr_ddr_n = 1'b0;
|
||||
reg_8b_16bn = 1'b0;
|
||||
stream = 1'b0;
|
||||
#500 transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
|
||||
#500;
|
||||
|
||||
// Stream SDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
sdr_ddr_n = 1'b1;
|
||||
reg_8b_16bn = 1'b0;
|
||||
stream = 1'b1;
|
||||
transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
#1000 stream = 1'b0;
|
||||
|
||||
#500;
|
||||
|
||||
// Stream DDR
|
||||
|
||||
address_write = 8'h2c;
|
||||
reg_8b_16bn = 1'b1;
|
||||
sdr_ddr_n = 1'b0;
|
||||
stream = 1'b1;
|
||||
transfer_data = 1'b1;
|
||||
#100 transfer_data = 1'b0;
|
||||
#1000 stream = 1'b0;
|
||||
|
||||
end
|
||||
|
||||
// data is incremented at each complete cycle
|
||||
|
||||
assign dac_data_final = (stream == 1'b1) ? dac_data : data_write;
|
||||
assign data_increment_valid = (sdr_ddr_n ) ? 5'd16: 5'h8;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (valid_counter == data_increment_valid) begin
|
||||
dac_data <= dac_data + 32'h00010002;
|
||||
valid_counter <= 3'b0;
|
||||
dac_data_valid <= 1'b1;
|
||||
end else begin
|
||||
dac_data <= dac_data;
|
||||
valid_counter <= valid_counter + 3'b1;
|
||||
dac_data_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// data is circullary shifted at every sampling edge
|
||||
|
||||
assign readback_data_shift = (sdr_ddr_n ) ? 4'h8 : 4'h4;
|
||||
assign sdio_i = (sdio_t === 1'b1) ? transfer_reg[31:28] : 4'b0;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (shift_count == readback_data_shift) begin
|
||||
transfer_reg <= {transfer_reg[27:0],transfer_reg[31:28]};
|
||||
end else if (sdio_t === 1'b1) begin
|
||||
transfer_reg <= transfer_reg;
|
||||
end
|
||||
if (shift_count == readback_data_shift || dac_csn == 1'b1) begin
|
||||
shift_count <= 3'b0;
|
||||
end else if (sdio_t === 1'b1) begin
|
||||
shift_count <= shift_count + 3'b1;
|
||||
end
|
||||
end
|
||||
|
||||
axi_ad3552r_if axi_ad3552r_interface (
|
||||
.clk_in(dac_clk),
|
||||
.reset_in(reset_in),
|
||||
.dac_data(dac_data_final),
|
||||
.dac_data_valid(dac_data_valid),
|
||||
.address(address_write),
|
||||
.data_read(data_read),
|
||||
.data_write(data_write),
|
||||
.sdr_ddr_n(sdr_ddr_n),
|
||||
.symb_8_16b(reg_8b_16bn),
|
||||
.transfer_data(transfer_data),
|
||||
.stream(stream),
|
||||
.dac_data_ready(dac_data_ready),
|
||||
.if_busy(if_busy),
|
||||
.sclk(dac_sclk),
|
||||
.csn(dac_csn),
|
||||
.sdio_i(sdio_i),
|
||||
.sdio_o(sdio_o),
|
||||
.sdio_t(sdio_t));
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,51 @@
|
|||
###############################################################################
|
||||
## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
|
||||
### SPDX short identifier: ADIBSD
|
||||
###############################################################################
|
||||
|
||||
source ../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl
|
||||
|
||||
adi_ip_create axi_ad3552r
|
||||
adi_ip_files axi_ad3552r [list \
|
||||
"$ad_hdl_dir/library/xilinx/common/ad_mul.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/common/ad_dds_cordic_pipe.v" \
|
||||
"$ad_hdl_dir/library/common/ad_dds_sine_cordic.v" \
|
||||
"$ad_hdl_dir/library/common/ad_dds_sine.v" \
|
||||
"$ad_hdl_dir/library/common/ad_dds_2.v" \
|
||||
"$ad_hdl_dir/library/common/ad_dds_1.v" \
|
||||
"$ad_hdl_dir/library/common/ad_dds.v" \
|
||||
"$ad_hdl_dir/library/common/ad_addsub.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" \
|
||||
"axi_ad3552r_channel.v" \
|
||||
"axi_ad3552r_core.v" \
|
||||
"axi_ad3552r_if.v" \
|
||||
"axi_ad3552r.v" ]
|
||||
|
||||
adi_ip_properties axi_ad3552r
|
||||
adi_init_bd_tcl
|
||||
adi_ip_bd axi_ad3552r "bd/bd.tcl"
|
||||
|
||||
set cc [ipx::current_core]
|
||||
|
||||
set_property company_url {https://wiki.analog.com/resources/fpga/docs/axi_ad3552r} $cc
|
||||
|
||||
set_property driver_value 0 [ipx::get_ports *dac* -of_objects $cc]
|
||||
set_property driver_value 0 [ipx::get_ports *data* -of_objects $cc]
|
||||
set_property driver_value 0 [ipx::get_ports *valid* -of_objects $cc]
|
||||
ipx::infer_bus_interface dac_clk xilinx.com:signal:clock_rtl:1.0 $cc
|
||||
|
||||
adi_add_auto_fpga_spec_params
|
||||
|
||||
ipx::create_xgui_files $cc
|
||||
ipx::save_core $cc
|
Loading…
Reference in New Issue