initial checkin

main
Rejeesh Kutty 2014-02-28 14:26:22 -05:00
parent 64b7269288
commit f7c9368abc
68 changed files with 40504 additions and 0 deletions

View File

@ -0,0 +1,223 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// software programmable clock generator (still needs a reference input!)
module axi_clkgen (
// clocks
clk,
clk_0,
clk_1,
drp_clk,
// axi interface
s_axi_aclk,
s_axi_aresetn,
s_axi_awvalid,
s_axi_awaddr,
s_axi_awready,
s_axi_wvalid,
s_axi_wdata,
s_axi_wstrb,
s_axi_wready,
s_axi_bvalid,
s_axi_bresp,
s_axi_bready,
s_axi_arvalid,
s_axi_araddr,
s_axi_arready,
s_axi_rvalid,
s_axi_rdata,
s_axi_rresp,
s_axi_rready);
// parameters
parameter PCORE_ID = 0;
parameter PCORE_DEVICE_TYPE = 0;
parameter PCORE_CLKIN_PERIOD = 5.0;
parameter PCORE_VCO_DIV = 11;
parameter PCORE_VCO_MUL = 49;
parameter PCORE_CLK0_DIV = 6;
parameter PCORE_CLK1_DIV = 6;
parameter C_S_AXI_MIN_SIZE = 32'hffff;
parameter C_BASEADDR = 32'hffffffff;
parameter C_HIGHADDR = 32'h00000000;
// clocks
input clk;
output clk_0;
output clk_1;
input drp_clk;
// axi interface
input s_axi_aclk;
input s_axi_aresetn;
input s_axi_awvalid;
input [31:0] s_axi_awaddr;
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 [31:0] s_axi_araddr;
output s_axi_arready;
output s_axi_rvalid;
output [31:0] s_axi_rdata;
output [ 1:0] s_axi_rresp;
input s_axi_rready;
// reset and clocks
wire mmcm_rst;
wire drp_rst;
wire up_rstn;
wire up_clk;
// internal signals
wire drp_sel_s;
wire drp_wr_s;
wire [11:0] drp_addr_s;
wire [15:0] drp_wdata_s;
wire [15:0] drp_rdata_s;
wire drp_ready_s;
wire drp_locked_s;
wire up_sel_s;
wire up_wr_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
wire [31:0] up_rdata_s;
wire up_ack_s;
// signal name changes
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
// up bus interface
up_axi #(
.PCORE_BASEADDR (C_BASEADDR),
.PCORE_HIGHADDR (C_HIGHADDR))
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_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s),
.up_ack (up_ack_s));
// processor interface
up_clkgen i_up_clkgen (
.mmcm_rst (mmcm_rst),
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel_s),
.drp_wr (drp_wr_s),
.drp_addr (drp_addr_s),
.drp_wdata (drp_wdata_s),
.drp_rdata (drp_rdata_s),
.drp_ready (drp_ready_s),
.drp_locked (drp_locked_s),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s),
.up_ack (up_ack_s));
// mmcm instantiations
ad_mmcm_drp #(
.MMCM_DEVICE_TYPE (PCORE_DEVICE_TYPE),
.MMCM_CLKIN_PERIOD (PCORE_CLKIN_PERIOD),
.MMCM_VCO_DIV (PCORE_VCO_DIV),
.MMCM_VCO_MUL (PCORE_VCO_MUL),
.MMCM_CLK0_DIV (PCORE_CLK0_DIV),
.MMCM_CLK1_DIV (PCORE_CLK1_DIV))
i_mmcm_drp (
.clk (clk),
.mmcm_rst (mmcm_rst),
.mmcm_clk_0 (clk_0),
.mmcm_clk_1 (clk_1),
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel_s),
.drp_wr (drp_wr_s),
.drp_addr (drp_addr_s),
.drp_wdata (drp_wdata_s),
.drp_rdata (drp_rdata_s),
.drp_ready (drp_ready_s),
.drp_locked (drp_locked_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,23 @@
# ip
source ../scripts/adi_ip.tcl
adi_ip_create axi_clkgen
adi_ip_files axi_clkgen [list \
"../common/ad_rst.v" \
"../common/ad_mmcm_drp.v" \
"../common/up_axi.v" \
"../common/up_drp_cntrl.v" \
"../common/up_clkgen.v" \
"axi_clkgen.v" ]
adi_ip_properties axi_clkgen
set_property physical_name {s_axi_aclk} [ipx::get_port_map CLK \
[ipx::get_bus_interface s_axi_signal_clock [ipx::current_core]]]
ipx::remove_bus_interface {signal_clock} [ipx::current_core]
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,377 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
module axi_hdmi_tx (
// hdmi interface
hdmi_clk,
hdmi_out_clk,
// 16-bit interface
hdmi_16_hsync,
hdmi_16_vsync,
hdmi_16_data_e,
hdmi_16_data,
hdmi_16_es_data,
// 24-bit interface
hdmi_24_hsync,
hdmi_24_vsync,
hdmi_24_data_e,
hdmi_24_data,
// 36-bit interface
hdmi_36_hsync,
hdmi_36_vsync,
hdmi_36_data_e,
hdmi_36_data,
// vdma interface
m_axis_mm2s_clk,
m_axis_mm2s_fsync,
m_axis_mm2s_fsync_ret,
m_axis_mm2s_tvalid,
m_axis_mm2s_tdata,
m_axis_mm2s_tkeep,
m_axis_mm2s_tlast,
m_axis_mm2s_tready,
// axi interface
s_axi_aclk,
s_axi_aresetn,
s_axi_awvalid,
s_axi_awaddr,
s_axi_awready,
s_axi_wvalid,
s_axi_wdata,
s_axi_wstrb,
s_axi_wready,
s_axi_bvalid,
s_axi_bresp,
s_axi_bready,
s_axi_arvalid,
s_axi_araddr,
s_axi_arready,
s_axi_rvalid,
s_axi_rdata,
s_axi_rresp,
s_axi_rready);
// parameters
parameter PCORE_ID = 0;
parameter PCORE_Cr_Cb_N = 0;
parameter PCORE_DEVICE_TYPE = 0;
parameter PCORE_EMBEDDED_SYNC = 0;
parameter C_S_AXI_MIN_SIZE = 32'hffff;
parameter C_BASEADDR = 32'hffffffff;
parameter C_HIGHADDR = 32'h00000000;
// hdmi interface
input hdmi_clk;
output hdmi_out_clk;
// 16-bit interface
output hdmi_16_hsync;
output hdmi_16_vsync;
output hdmi_16_data_e;
output [15:0] hdmi_16_data;
output [15:0] hdmi_16_es_data;
// 24-bit interface
output hdmi_24_hsync;
output hdmi_24_vsync;
output hdmi_24_data_e;
output [23:0] hdmi_24_data;
// 36-bit interface
output hdmi_36_hsync;
output hdmi_36_vsync;
output hdmi_36_data_e;
output [35:0] hdmi_36_data;
// vdma interface
input m_axis_mm2s_clk;
output m_axis_mm2s_fsync;
input m_axis_mm2s_fsync_ret;
input m_axis_mm2s_tvalid;
input [63:0] m_axis_mm2s_tdata;
input [ 7:0] m_axis_mm2s_tkeep;
input m_axis_mm2s_tlast;
output m_axis_mm2s_tready;
// axi interface
input s_axi_aclk;
input s_axi_aresetn;
input s_axi_awvalid;
input [31:0] s_axi_awaddr;
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 [31:0] s_axi_araddr;
output s_axi_arready;
output s_axi_rvalid;
output [31:0] s_axi_rdata;
output [ 1:0] s_axi_rresp;
input s_axi_rready;
// reset and clocks
wire up_rstn;
wire up_clk;
wire hdmi_rst;
wire vdma_clk;
wire vdma_rst;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
wire [31:0] up_rdata_s;
wire up_ack_s;
wire hdmi_full_range_s;
wire hdmi_csc_bypass_s;
wire [ 1:0] hdmi_srcsel_s;
wire [23:0] hdmi_const_rgb_s;
wire [15:0] hdmi_hl_active_s;
wire [15:0] hdmi_hl_width_s;
wire [15:0] hdmi_hs_width_s;
wire [15:0] hdmi_he_max_s;
wire [15:0] hdmi_he_min_s;
wire [15:0] hdmi_vf_active_s;
wire [15:0] hdmi_vf_width_s;
wire [15:0] hdmi_vs_width_s;
wire [15:0] hdmi_ve_max_s;
wire [15:0] hdmi_ve_min_s;
wire hdmi_fs_toggle_s;
wire [ 8:0] hdmi_raddr_g_s;
wire hdmi_tpm_oos_s;
wire hdmi_status_s;
wire vdma_fs_s;
wire vdma_fs_ret_s;
wire vdma_valid_s;
wire [63:0] vdma_data_s;
wire vdma_ready_s;
wire vdma_wr_s;
wire [ 8:0] vdma_waddr_s;
wire [47:0] vdma_wdata_s;
wire vdma_fs_ret_toggle_s;
wire [ 8:0] vdma_fs_waddr_s;
// signal name changes
assign up_rstn = s_axi_aresetn;
assign up_clk = s_axi_aclk;
assign vdma_clk = m_axis_mm2s_clk;
assign vdma_valid_s = m_axis_mm2s_tvalid;
assign vdma_data_s = m_axis_mm2s_tdata;
assign vdma_fs_ret_s = m_axis_mm2s_fsync_ret;
assign m_axis_mm2s_fsync = vdma_fs_s;
assign m_axis_mm2s_tready = vdma_ready_s;
// axi interface
up_axi #(
.PCORE_BASEADDR (C_BASEADDR),
.PCORE_HIGHADDR (C_HIGHADDR))
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_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s),
.up_ack (up_ack_s));
// processor interface
up_hdmi_tx i_up (
.hdmi_clk (hdmi_clk),
.hdmi_rst (hdmi_rst),
.hdmi_full_range (hdmi_full_range_s),
.hdmi_csc_bypass (hdmi_csc_bypass_s),
.hdmi_srcsel (hdmi_srcsel_s),
.hdmi_const_rgb (hdmi_const_rgb_s),
.hdmi_hl_active (hdmi_hl_active_s),
.hdmi_hl_width (hdmi_hl_width_s),
.hdmi_hs_width (hdmi_hs_width_s),
.hdmi_he_max (hdmi_he_max_s),
.hdmi_he_min (hdmi_he_min_s),
.hdmi_vf_active (hdmi_vf_active_s),
.hdmi_vf_width (hdmi_vf_width_s),
.hdmi_vs_width (hdmi_vs_width_s),
.hdmi_ve_max (hdmi_ve_max_s),
.hdmi_ve_min (hdmi_ve_min_s),
.hdmi_status (hdmi_status_s),
.hdmi_tpm_oos (hdmi_tpm_oos_s),
.hdmi_clk_ratio (32'd1),
.vdma_clk (vdma_clk),
.vdma_rst (vdma_rst),
.vdma_ovf (vdma_ovf_s),
.vdma_unf (vdma_unf_s),
.vdma_tpm_oos (vdma_tpm_oos_s),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s),
.up_ack (up_ack_s));
// vdma interface
axi_hdmi_tx_vdma i_vdma (
.hdmi_fs_toggle (hdmi_fs_toggle_s),
.hdmi_raddr_g (hdmi_raddr_g_s),
.vdma_clk (vdma_clk),
.vdma_rst (vdma_rst),
.vdma_fs (vdma_fs_s),
.vdma_fs_ret (vdma_fs_ret_s),
.vdma_valid (vdma_valid_s),
.vdma_data (vdma_data_s),
.vdma_ready (vdma_ready_s),
.vdma_wr (vdma_wr_s),
.vdma_waddr (vdma_waddr_s),
.vdma_wdata (vdma_wdata_s),
.vdma_fs_ret_toggle (vdma_fs_ret_toggle_s),
.vdma_fs_waddr (vdma_fs_waddr_s),
.vdma_tpm_oos (vdma_tpm_oos_s),
.vdma_ovf (vdma_ovf_s),
.vdma_unf (vdma_unf_s));
// hdmi interface
axi_hdmi_tx_core #(
.Cr_Cb_N(PCORE_Cr_Cb_N),
.EMBEDDED_SYNC(PCORE_EMBEDDED_SYNC))
i_tx_core (
.hdmi_clk (hdmi_clk),
.hdmi_rst (hdmi_rst),
.hdmi_16_hsync (hdmi_16_hsync),
.hdmi_16_vsync (hdmi_16_vsync),
.hdmi_16_data_e (hdmi_16_data_e),
.hdmi_16_data (hdmi_16_data),
.hdmi_16_es_data (hdmi_16_es_data),
.hdmi_24_hsync (hdmi_24_hsync),
.hdmi_24_vsync (hdmi_24_vsync),
.hdmi_24_data_e (hdmi_24_data_e),
.hdmi_24_data (hdmi_24_data),
.hdmi_36_hsync (hdmi_36_hsync),
.hdmi_36_vsync (hdmi_36_vsync),
.hdmi_36_data_e (hdmi_36_data_e),
.hdmi_36_data (hdmi_36_data),
.hdmi_fs_toggle (hdmi_fs_toggle_s),
.hdmi_raddr_g (hdmi_raddr_g_s),
.hdmi_tpm_oos (hdmi_tpm_oos_s),
.hdmi_status (hdmi_status_s),
.vdma_clk (vdma_clk),
.vdma_wr (vdma_wr_s),
.vdma_waddr (vdma_waddr_s),
.vdma_wdata (vdma_wdata_s),
.vdma_fs_ret_toggle (vdma_fs_ret_toggle_s),
.vdma_fs_waddr (vdma_fs_waddr_s),
.hdmi_full_range (hdmi_full_range_s),
.hdmi_csc_bypass (hdmi_csc_bypass_s),
.hdmi_srcsel (hdmi_srcsel_s),
.hdmi_const_rgb (hdmi_const_rgb_s),
.hdmi_hl_active (hdmi_hl_active_s),
.hdmi_hl_width (hdmi_hl_width_s),
.hdmi_hs_width (hdmi_hs_width_s),
.hdmi_he_max (hdmi_he_max_s),
.hdmi_he_min (hdmi_he_min_s),
.hdmi_vf_active (hdmi_vf_active_s),
.hdmi_vf_width (hdmi_vf_width_s),
.hdmi_vs_width (hdmi_vs_width_s),
.hdmi_ve_max (hdmi_ve_max_s),
.hdmi_ve_min (hdmi_ve_min_s));
// hdmi output clock
ODDR #(.INIT(1'b0)) i_clk_oddr (
.R (1'b0),
.S (1'b0),
.CE (1'b1),
.D1 (1'b1),
.D2 (1'b0),
.C (hdmi_clk),
.Q (hdmi_out_clk));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,615 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Transmit HDMI, video dma data in, hdmi separate syncs data out.
module axi_hdmi_tx_core (
// hdmi interface
hdmi_clk,
hdmi_rst,
// 16-bit interface
hdmi_16_hsync,
hdmi_16_vsync,
hdmi_16_data_e,
hdmi_16_data,
hdmi_16_es_data,
// 24-bit interface
hdmi_24_hsync,
hdmi_24_vsync,
hdmi_24_data_e,
hdmi_24_data,
// 36-bit interface
hdmi_36_hsync,
hdmi_36_vsync,
hdmi_36_data_e,
hdmi_36_data,
// control signals
hdmi_fs_toggle,
hdmi_raddr_g,
hdmi_tpm_oos,
hdmi_status,
// vdma interface
vdma_clk,
vdma_wr,
vdma_waddr,
vdma_wdata,
vdma_fs_ret_toggle,
vdma_fs_waddr,
// processor interface
hdmi_full_range,
hdmi_csc_bypass,
hdmi_srcsel,
hdmi_const_rgb,
hdmi_hl_active,
hdmi_hl_width,
hdmi_hs_width,
hdmi_he_max,
hdmi_he_min,
hdmi_vf_active,
hdmi_vf_width,
hdmi_vs_width,
hdmi_ve_max,
hdmi_ve_min);
// parameters
parameter Cr_Cb_N = 0;
parameter EMBEDDED_SYNC = 0;
// hdmi interface
input hdmi_clk;
input hdmi_rst;
// 16-bit interface
output hdmi_16_hsync;
output hdmi_16_vsync;
output hdmi_16_data_e;
output [15:0] hdmi_16_data;
output [15:0] hdmi_16_es_data;
// 24-bit interface
output hdmi_24_hsync;
output hdmi_24_vsync;
output hdmi_24_data_e;
output [23:0] hdmi_24_data;
// 36-bit interface
output hdmi_36_hsync;
output hdmi_36_vsync;
output hdmi_36_data_e;
output [35:0] hdmi_36_data;
// control signals
output hdmi_fs_toggle;
output [ 8:0] hdmi_raddr_g;
output hdmi_tpm_oos;
output hdmi_status;
// vdma interface
input vdma_clk;
input vdma_wr;
input [ 8:0] vdma_waddr;
input [47:0] vdma_wdata;
input vdma_fs_ret_toggle;
input [ 8:0] vdma_fs_waddr;
// processor interface
input hdmi_full_range;
input hdmi_csc_bypass;
input [ 1:0] hdmi_srcsel;
input [23:0] hdmi_const_rgb;
input [15:0] hdmi_hl_active;
input [15:0] hdmi_hl_width;
input [15:0] hdmi_hs_width;
input [15:0] hdmi_he_max;
input [15:0] hdmi_he_min;
input [15:0] hdmi_vf_active;
input [15:0] hdmi_vf_width;
input [15:0] hdmi_vs_width;
input [15:0] hdmi_ve_max;
input [15:0] hdmi_ve_min;
// internal registers
reg hdmi_status = 'd0;
reg hdmi_enable = 'd0;
reg [15:0] hdmi_hs_count = 'd0;
reg [15:0] hdmi_vs_count = 'd0;
reg hdmi_fs = 'd0;
reg hdmi_fs_toggle = 'd0;
reg hdmi_fs_ret_toggle_m1 = 'd0;
reg hdmi_fs_ret_toggle_m2 = 'd0;
reg hdmi_fs_ret_toggle_m3 = 'd0;
reg hdmi_fs_ret = 'd0;
reg [ 8:0] hdmi_fs_waddr = 'd0;
reg hdmi_hs = 'd0;
reg hdmi_vs = 'd0;
reg hdmi_hs_de = 'd0;
reg hdmi_vs_de = 'd0;
reg [ 9:0] hdmi_raddr = 'd0;
reg [ 8:0] hdmi_raddr_g = 'd0;
reg hdmi_hs_d = 'd0;
reg hdmi_vs_d = 'd0;
reg hdmi_hs_de_d = 'd0;
reg hdmi_vs_de_d = 'd0;
reg hdmi_de_d = 'd0;
reg hdmi_data_sel_d = 'd0;
reg hdmi_hs_2d = 'd0;
reg hdmi_vs_2d = 'd0;
reg hdmi_hs_de_2d = 'd0;
reg hdmi_vs_de_2d = 'd0;
reg hdmi_de_2d = 'd0;
reg hdmi_data_sel_2d = 'd0;
reg [47:0] hdmi_data_2d = 'd0;
reg [23:0] hdmi_tpm_data = 'd0;
reg hdmi_tpm_oos = 'd0;
reg hdmi_hsync = 'd0;
reg hdmi_vsync = 'd0;
reg hdmi_hsync_data_e = 'd0;
reg hdmi_vsync_data_e = 'd0;
reg hdmi_data_e = 'd0;
reg [23:0] hdmi_data = 'd0;
reg hdmi_24_hsync = 'd0;
reg hdmi_24_vsync = 'd0;
reg hdmi_24_hsync_data_e = 'd0;
reg hdmi_24_vsync_data_e = 'd0;
reg hdmi_24_data_e = 'd0;
reg [23:0] hdmi_24_data = 'd0;
reg hdmi_16_hsync = 'd0;
reg hdmi_16_vsync = 'd0;
reg hdmi_16_data_e = 'd0;
reg [15:0] hdmi_16_data = 'd0;
reg hdmi_es_hs_de = 'd0;
reg hdmi_es_vs_de = 'd0;
reg [15:0] hdmi_es_data = 'd0;
reg hdmi_es_hs_de_d = 'd0;
reg [15:0] hdmi_es_data_d = 'd0;
reg hdmi_es_hs_de_2d = 'd0;
reg [15:0] hdmi_es_data_2d = 'd0;
reg hdmi_es_hs_de_3d = 'd0;
reg [15:0] hdmi_es_data_3d = 'd0;
reg hdmi_es_hs_de_4d = 'd0;
reg [15:0] hdmi_es_data_4d = 'd0;
reg hdmi_es_hs_de_5d = 'd0;
reg [15:0] hdmi_es_data_5d = 'd0;
reg [15:0] hdmi_es_data_6d = 'd0;
// internal wires
wire [15:0] hdmi_hl_width_s;
wire [15:0] hdmi_vf_width_s;
wire [15:0] hdmi_he_width_s;
wire [15:0] hdmi_ve_width_s;
wire hdmi_fs_ret_s;
wire hdmi_de_s;
wire [47:0] hdmi_rdata_s;
wire [23:0] hdmi_data_2d_s;
wire hdmi_tpm_mismatch_s;
wire [23:0] hdmi_tpg_data_s;
wire hdmi_csc_hsync_s;
wire hdmi_csc_vsync_s;
wire hdmi_csc_hsync_data_e_s;
wire hdmi_csc_vsync_data_e_s;
wire hdmi_csc_data_e_s;
wire [23:0] hdmi_csc_data_s;
wire hdmi_ss_hsync_s;
wire hdmi_ss_vsync_s;
wire hdmi_ss_hsync_data_e_s;
wire hdmi_ss_vsync_data_e_s;
wire hdmi_ss_data_e_s;
wire [15:0] hdmi_ss_data_s;
wire hdmi_es_hs_de_s;
wire hdmi_es_vs_de_s;
wire hdmi_es_de_s;
wire [15:0] hdmi_es_data_s;
wire [15:0] hdmi_es_sav_s;
wire [15:0] hdmi_es_eav_s;
// binary to grey conversion
function [8:0] b2g;
input [8:0] b;
reg [8:0] g;
begin
g[8] = b[8];
g[7] = b[8] ^ b[7];
g[6] = b[7] ^ b[6];
g[5] = b[6] ^ b[5];
g[4] = b[5] ^ b[4];
g[3] = b[4] ^ b[3];
g[2] = b[3] ^ b[2];
g[1] = b[2] ^ b[1];
g[0] = b[1] ^ b[0];
b2g = g;
end
endfunction
// status and enable
always @(posedge hdmi_clk) begin
if (hdmi_rst == 1'b1) begin
hdmi_status <= 1'b0;
hdmi_enable <= 1'b0;
end else begin
hdmi_status <= 1'b1;
hdmi_enable <= hdmi_srcsel[1] | hdmi_srcsel[0];
end
end
// calculate useful limits
assign hdmi_hl_width_s = hdmi_hl_width - 1'b1;
assign hdmi_vf_width_s = hdmi_vf_width - 1'b1;
assign hdmi_he_width_s = hdmi_hl_width - (hdmi_hl_active + 1'b1);
assign hdmi_ve_width_s = hdmi_vf_width - (hdmi_vf_active + 1'b1);
// hdmi counters
always @(posedge hdmi_clk) begin
if (hdmi_hs_count >= hdmi_hl_width_s) begin
hdmi_hs_count <= 0;
end else begin
hdmi_hs_count <= hdmi_hs_count + 1'b1;
end
if (hdmi_hs_count >= hdmi_hl_width_s) begin
if (hdmi_vs_count >= hdmi_vf_width_s) begin
hdmi_vs_count <= 0;
end else begin
hdmi_vs_count <= hdmi_vs_count + 1'b1;
end
end
end
// hdmi start of frame
always @(posedge hdmi_clk) begin
if (EMBEDDED_SYNC == 1) begin
if ((hdmi_hs_count == 1) && (hdmi_vs_count == hdmi_ve_width_s)) begin
hdmi_fs <= hdmi_enable;
end else begin
hdmi_fs <= 1'b0;
end
end else begin
if ((hdmi_hs_count == 1) && (hdmi_vs_count == hdmi_vs_width)) begin
hdmi_fs <= hdmi_enable;
end else begin
hdmi_fs <= 1'b0;
end
end
if (hdmi_fs == 1'b1) begin
hdmi_fs_toggle <= ~hdmi_fs_toggle;
end
end
// hdmi sof write address
assign hdmi_fs_ret_s = hdmi_fs_ret_toggle_m2 ^ hdmi_fs_ret_toggle_m3;
always @(posedge hdmi_clk) begin
if (hdmi_rst == 1'b1) begin
hdmi_fs_ret_toggle_m1 <= 1'd0;
hdmi_fs_ret_toggle_m2 <= 1'd0;
hdmi_fs_ret_toggle_m3 <= 1'd0;
end else begin
hdmi_fs_ret_toggle_m1 <= vdma_fs_ret_toggle;
hdmi_fs_ret_toggle_m2 <= hdmi_fs_ret_toggle_m1;
hdmi_fs_ret_toggle_m3 <= hdmi_fs_ret_toggle_m2;
end
hdmi_fs_ret <= hdmi_fs_ret_s;
if (hdmi_fs_ret_s == 1'b1) begin
hdmi_fs_waddr <= vdma_fs_waddr;
end
end
// hdmi sync signals
always @(posedge hdmi_clk) begin
if (EMBEDDED_SYNC == 1) begin
hdmi_hs <= 1'b0;
hdmi_vs <= 1'b0;
if (hdmi_hs_count <= hdmi_he_width_s) begin
hdmi_hs_de <= 1'b0;
end else begin
hdmi_hs_de <= hdmi_enable;
end
if (hdmi_vs_count <= hdmi_ve_width_s) begin
hdmi_vs_de <= 1'b0;
end else begin
hdmi_vs_de <= hdmi_enable;
end
end else begin
if (hdmi_hs_count < hdmi_hs_width) begin
hdmi_hs <= hdmi_enable;
end else begin
hdmi_hs <= 1'b0;
end
if (hdmi_vs_count < hdmi_vs_width) begin
hdmi_vs <= hdmi_enable;
end else begin
hdmi_vs <= 1'b0;
end
if ((hdmi_hs_count < hdmi_he_min) || (hdmi_hs_count >= hdmi_he_max)) begin
hdmi_hs_de <= 1'b0;
end else begin
hdmi_hs_de <= hdmi_enable;
end
if ((hdmi_vs_count < hdmi_ve_min) || (hdmi_vs_count >= hdmi_ve_max)) begin
hdmi_vs_de <= 1'b0;
end else begin
hdmi_vs_de <= hdmi_enable;
end
end
end
// hdmi read data
assign hdmi_de_s = hdmi_hs_de & hdmi_vs_de;
always @(posedge hdmi_clk) begin
if (hdmi_rst == 1'b1) begin
hdmi_raddr <= 10'd0;
end else if (hdmi_fs_ret == 1'b1) begin
hdmi_raddr <= {hdmi_fs_waddr, 1'b0};
end else if (hdmi_de_s == 1'b1) begin
hdmi_raddr <= hdmi_raddr + 1'b1;
end
hdmi_raddr_g <= b2g(hdmi_raddr[9:1]);
end
// control and data pipe line
always @(posedge hdmi_clk) begin
hdmi_hs_d <= hdmi_hs;
hdmi_vs_d <= hdmi_vs;
hdmi_hs_de_d <= hdmi_hs_de;
hdmi_vs_de_d <= hdmi_vs_de;
hdmi_de_d <= hdmi_de_s;
hdmi_data_sel_d <= hdmi_raddr[0];
hdmi_hs_2d <= hdmi_hs_d;
hdmi_vs_2d <= hdmi_vs_d;
hdmi_hs_de_2d <= hdmi_hs_de_d;
hdmi_vs_de_2d <= hdmi_vs_de_d;
hdmi_de_2d <= hdmi_de_d;
hdmi_data_sel_2d <= hdmi_data_sel_d;
hdmi_data_2d <= hdmi_rdata_s;
end
// hdmi data count (may be used to monitor or insert)
assign hdmi_data_2d_s = (hdmi_data_sel_2d == 1'b1) ? hdmi_data_2d[47:24] : hdmi_data_2d[23:0];
assign hdmi_tpm_mismatch_s = (hdmi_data_2d_s == hdmi_tpm_data) ? 1'b0 : hdmi_de_2d;
assign hdmi_tpg_data_s = hdmi_tpm_data;
always @(posedge hdmi_clk) begin
if ((hdmi_rst == 1'b1) || (hdmi_fs_ret == 1'b1)) begin
hdmi_tpm_data <= 'd0;
end else if (hdmi_de_2d == 1'b1) begin
hdmi_tpm_data <= hdmi_tpm_data + 1'b1;
end
hdmi_tpm_oos <= hdmi_tpm_mismatch_s;
end
// hdmi data select
always @(posedge hdmi_clk) begin
hdmi_hsync <= hdmi_hs_2d;
hdmi_vsync <= hdmi_vs_2d;
hdmi_hsync_data_e <= hdmi_hs_de_2d;
hdmi_vsync_data_e <= hdmi_vs_de_2d;
hdmi_data_e <= hdmi_de_2d;
case (hdmi_srcsel)
2'b11: hdmi_data <= hdmi_const_rgb;
2'b10: hdmi_data <= hdmi_tpg_data_s;
2'b01: hdmi_data <= hdmi_data_2d_s;
default: hdmi_data <= 24'd0;
endcase
end
// hdmi csc 16, 24 and 36 outputs
assign hdmi_36_hsync = hdmi_24_hsync;
assign hdmi_36_vsync = hdmi_24_vsync;
assign hdmi_36_data_e = hdmi_24_data_e;
assign hdmi_36_data[35:24] = {hdmi_24_data[23:16], hdmi_24_data[23:20]};
assign hdmi_36_data[23:12] = {hdmi_24_data[15: 8], hdmi_24_data[15:12]};
assign hdmi_36_data[11: 0] = {hdmi_24_data[ 7: 0], hdmi_24_data[ 7: 4]};
always @(posedge hdmi_clk) begin
if (hdmi_csc_bypass == 1'b1) begin
hdmi_24_hsync <= hdmi_hsync;
hdmi_24_vsync <= hdmi_vsync;
hdmi_24_hsync_data_e <= hdmi_hsync_data_e;
hdmi_24_vsync_data_e <= hdmi_vsync_data_e;
hdmi_24_data_e <= hdmi_data_e;
hdmi_24_data <= hdmi_data;
end else begin
hdmi_24_hsync <= hdmi_csc_hsync_s;
hdmi_24_vsync <= hdmi_csc_vsync_s;
hdmi_24_hsync_data_e <= hdmi_csc_hsync_data_e_s;
hdmi_24_vsync_data_e <= hdmi_csc_vsync_data_e_s;
hdmi_24_data_e <= hdmi_csc_data_e_s;
hdmi_24_data <= hdmi_csc_data_s;
end
hdmi_16_hsync <= hdmi_ss_hsync_s;
hdmi_16_vsync <= hdmi_ss_vsync_s;
hdmi_16_data_e <= hdmi_ss_data_e_s;
hdmi_16_data <= hdmi_ss_data_s;
end
// hdmi embedded sync clipping
assign hdmi_es_hs_de_s = hdmi_ss_hsync_data_e_s;
assign hdmi_es_vs_de_s = hdmi_ss_vsync_data_e_s;
assign hdmi_es_de_s = hdmi_ss_data_e_s;
assign hdmi_es_data_s = hdmi_ss_data_s;
always @(posedge hdmi_clk) begin
hdmi_es_hs_de <= hdmi_es_hs_de_s;
hdmi_es_vs_de <= hdmi_es_vs_de_s;
if (hdmi_es_de_s == 1'b0) begin
hdmi_es_data[15:8] <= 8'h80;
end else if ((hdmi_full_range == 1'b0) &&
(hdmi_es_data_s[15:8] > 8'heb)) begin
hdmi_es_data[15:8] <= 8'heb;
end else if ((hdmi_full_range == 1'b1) &&
(hdmi_es_data_s[15:8] < 8'h10)) begin
hdmi_es_data[15:8] <= 8'h10;
end else begin
hdmi_es_data[15:8] <= hdmi_es_data_s[15:8];
end
if (hdmi_es_de_s == 1'b0) begin
hdmi_es_data[7:0] <= 8'h80;
end else if ((hdmi_full_range == 1'b0) &&
(hdmi_es_data_s[7:0] > 8'heb)) begin
hdmi_es_data[7:0] <= 8'heb;
end else if ((hdmi_full_range == 1'b1) &&
(hdmi_es_data_s[7:0] < 8'h10)) begin
hdmi_es_data[7:0] <= 8'h10;
end else begin
hdmi_es_data[7:0] <= hdmi_es_data_s[7:0];
end
end
// hdmi embedded sync insertion
assign hdmi_es_sav_s = (hdmi_es_vs_de == 1) ? 16'h8080 : 16'habab;
assign hdmi_es_eav_s = (hdmi_es_vs_de == 1) ? 16'h9d9d : 16'hb6b6;
always @(posedge hdmi_clk) begin
hdmi_es_hs_de_d <= hdmi_es_hs_de;
case ({hdmi_es_hs_de_4d, hdmi_es_hs_de_3d, hdmi_es_hs_de_2d,
hdmi_es_hs_de_d, hdmi_es_hs_de})
5'b10000: hdmi_es_data_d <= hdmi_es_eav_s;
5'b11000: hdmi_es_data_d <= 16'h0000;
5'b11100: hdmi_es_data_d <= 16'h0000;
5'b11110: hdmi_es_data_d <= 16'hffff;
default: hdmi_es_data_d <= hdmi_es_data;
endcase
hdmi_es_hs_de_2d <= hdmi_es_hs_de_d;
hdmi_es_data_2d <= hdmi_es_data_d;
hdmi_es_hs_de_3d <= hdmi_es_hs_de_2d;
hdmi_es_data_3d <= hdmi_es_data_2d;
hdmi_es_hs_de_4d <= hdmi_es_hs_de_3d;
hdmi_es_data_4d <= hdmi_es_data_3d;
hdmi_es_hs_de_5d <= hdmi_es_hs_de_4d;
hdmi_es_data_5d <= hdmi_es_data_4d;
case ({hdmi_es_hs_de_5d, hdmi_es_hs_de_4d, hdmi_es_hs_de_3d,
hdmi_es_hs_de_2d, hdmi_es_hs_de_d})
5'b01111: hdmi_es_data_6d <= hdmi_es_sav_s;
5'b00111: hdmi_es_data_6d <= 16'h0000;
5'b00011: hdmi_es_data_6d <= 16'h0000;
5'b00001: hdmi_es_data_6d <= 16'hffff;
default: hdmi_es_data_6d <= hdmi_es_data_5d;
endcase
end
// es outputs
assign hdmi_16_es_data = hdmi_es_data_6d;
// data memory
ad_mem #(.DATA_WIDTH(48), .ADDR_WIDTH(9)) i_mem (
.clka (vdma_clk),
.wea (vdma_wr),
.addra (vdma_waddr),
.dina (vdma_wdata),
.clkb (hdmi_clk),
.addrb (hdmi_raddr[9:1]),
.doutb (hdmi_rdata_s));
// color space coversion, RGB to CrYCb
ad_csc_RGB2CrYCb #(.DELAY_DATA_WIDTH(5)) i_csc_RGB2CrYCb (
.clk (hdmi_clk),
.RGB_sync ({hdmi_hsync,
hdmi_vsync,
hdmi_hsync_data_e,
hdmi_vsync_data_e,
hdmi_data_e}),
.RGB_data (hdmi_data),
.CrYCb_sync ({hdmi_csc_hsync_s,
hdmi_csc_vsync_s,
hdmi_csc_hsync_data_e_s,
hdmi_csc_vsync_data_e_s,
hdmi_csc_data_e_s}),
.CrYCb_data (hdmi_csc_data_s));
// sub sampling, 444 to 422
ad_ss_444to422 #(.DELAY_DATA_WIDTH(5), .Cr_Cb_N(Cr_Cb_N)) i_ss_444to422 (
.clk (hdmi_clk),
.s444_de (hdmi_24_data_e),
.s444_sync ({hdmi_24_hsync,
hdmi_24_vsync,
hdmi_24_hsync_data_e,
hdmi_24_vsync_data_e,
hdmi_24_data_e}),
.s444_data (hdmi_24_data),
.s422_sync ({hdmi_ss_hsync_s,
hdmi_ss_vsync_s,
hdmi_ss_hsync_data_e_s,
hdmi_ss_vsync_data_e_s,
hdmi_ss_data_e_s}),
.s422_data (hdmi_ss_data_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,26 @@
# ip
source ../scripts/adi_ip.tcl
adi_ip_create axi_hdmi_tx
adi_ip_files axi_hdmi_tx [list \
"../common/ad_mem.v" \
"../common/ad_rst.v" \
"../common/ad_csc_1_mul.v" \
"../common/ad_csc_1_add.v" \
"../common/ad_csc_1.v" \
"../common/ad_csc_RGB2CrYCb.v" \
"../common/ad_ss_444to422.v" \
"../common/up_axi.v" \
"../common/up_xfer_cntrl.v" \
"../common/up_xfer_status.v" \
"../common/up_clock_mon.v" \
"../common/up_hdmi_tx.v" \
"axi_hdmi_tx_vdma.v" \
"axi_hdmi_tx_core.v" \
"axi_hdmi_tx.v" ]
adi_ip_properties axi_hdmi_tx
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,230 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Transmit HDMI, video dma data in, hdmi separate syncs data out.
module axi_hdmi_tx_vdma (
// hdmi interface
hdmi_fs_toggle,
hdmi_raddr_g,
// vdma interface
vdma_clk,
vdma_rst,
vdma_fs,
vdma_fs_ret,
vdma_valid,
vdma_data,
vdma_ready,
vdma_wr,
vdma_waddr,
vdma_wdata,
vdma_fs_ret_toggle,
vdma_fs_waddr,
vdma_tpm_oos,
vdma_ovf,
vdma_unf);
// parameters
localparam BUF_THRESHOLD_LO = 9'd3;
localparam BUF_THRESHOLD_HI = 9'd509;
localparam RDY_THRESHOLD_LO = 9'd450;
localparam RDY_THRESHOLD_HI = 9'd500;
// hdmi interface
input hdmi_fs_toggle;
input [ 8:0] hdmi_raddr_g;
// vdma interface
input vdma_clk;
input vdma_rst;
output vdma_fs;
input vdma_fs_ret;
input vdma_valid;
input [63:0] vdma_data;
output vdma_ready;
output vdma_wr;
output [ 8:0] vdma_waddr;
output [47:0] vdma_wdata;
output vdma_fs_ret_toggle;
output [ 8:0] vdma_fs_waddr;
output vdma_tpm_oos;
output vdma_ovf;
output vdma_unf;
// internal registers
reg vdma_fs_toggle_m1 = 'd0;
reg vdma_fs_toggle_m2 = 'd0;
reg vdma_fs_toggle_m3 = 'd0;
reg vdma_fs = 'd0;
reg [ 8:0] vdma_fs_waddr = 'd0;
reg vdma_fs_ret_toggle = 'd0;
reg vdma_wr = 'd0;
reg [ 8:0] vdma_waddr = 'd0;
reg [47:0] vdma_wdata = 'd0;
reg [22:0] vdma_tpm_data = 'd0;
reg vdma_tpm_oos = 'd0;
reg [ 8:0] vdma_raddr_g_m1 = 'd0;
reg [ 8:0] vdma_raddr_g_m2 = 'd0;
reg [ 8:0] vdma_raddr = 'd0;
reg [ 8:0] vdma_addr_diff = 'd0;
reg vdma_ready = 'd0;
reg vdma_almost_full = 'd0;
reg vdma_almost_empty = 'd0;
reg vdma_ovf = 'd0;
reg vdma_unf = 'd0;
// internal wires
wire [47:0] vdma_tpm_data_s;
wire vdma_tpm_oos_s;
wire [ 9:0] vdma_addr_diff_s;
wire vdma_ovf_s;
wire vdma_unf_s;
// grey to binary conversion
function [8:0] g2b;
input [8:0] g;
reg [8:0] b;
begin
b[8] = g[8];
b[7] = b[8] ^ g[7];
b[6] = b[7] ^ g[6];
b[5] = b[6] ^ g[5];
b[4] = b[5] ^ g[4];
b[3] = b[4] ^ g[3];
b[2] = b[3] ^ g[2];
b[1] = b[2] ^ g[1];
b[0] = b[1] ^ g[0];
g2b = b;
end
endfunction
// get fs from hdmi side, return fs and sof write address back
always @(posedge vdma_clk) begin
if (vdma_rst == 1'b1) begin
vdma_fs_toggle_m1 <= 'd0;
vdma_fs_toggle_m2 <= 'd0;
vdma_fs_toggle_m3 <= 'd0;
end else begin
vdma_fs_toggle_m1 <= hdmi_fs_toggle;
vdma_fs_toggle_m2 <= vdma_fs_toggle_m1;
vdma_fs_toggle_m3 <= vdma_fs_toggle_m2;
end
vdma_fs <= vdma_fs_toggle_m2 ^ vdma_fs_toggle_m3;
if (vdma_fs_ret == 1'b1) begin
vdma_fs_waddr <= vdma_waddr;
vdma_fs_ret_toggle <= ~vdma_fs_ret_toggle;
end
end
// vdma write
always @(posedge vdma_clk) begin
vdma_wr <= vdma_valid & vdma_ready;
if (vdma_rst == 1'b1) begin
vdma_waddr <= 9'd0;
end else if (vdma_wr == 1'b1) begin
vdma_waddr <= vdma_waddr + 1'b1;
end
vdma_wdata <= {vdma_data[55:32], vdma_data[23:0]};
end
// test error conditions
assign vdma_tpm_data_s = {vdma_tpm_data, 1'b1, vdma_tpm_data, 1'b0};
assign vdma_tpm_oos_s = (vdma_wdata == vdma_tpm_data_s) ? 1'b0 : vdma_wr;
always @(posedge vdma_clk) begin
if ((vdma_rst == 1'b1) || (vdma_fs_ret == 1'b1)) begin
vdma_tpm_data <= 23'd0;
vdma_tpm_oos <= 1'd0;
end else if (vdma_wr == 1'b1) begin
vdma_tpm_data <= vdma_tpm_data + 1'b1;
vdma_tpm_oos <= vdma_tpm_oos_s;
end
end
// overflow or underflow status
assign vdma_addr_diff_s = {1'b1, vdma_waddr} - vdma_raddr;
assign vdma_ovf_s = (vdma_addr_diff < BUF_THRESHOLD_LO) ? vdma_almost_full : 1'b0;
assign vdma_unf_s = (vdma_addr_diff > BUF_THRESHOLD_HI) ? vdma_almost_empty : 1'b0;
always @(posedge vdma_clk) begin
if (vdma_rst == 1'b1) begin
vdma_raddr_g_m1 <= 9'd0;
vdma_raddr_g_m2 <= 9'd0;
end else begin
vdma_raddr_g_m1 <= hdmi_raddr_g;
vdma_raddr_g_m2 <= vdma_raddr_g_m1;
end
vdma_raddr <= g2b(vdma_raddr_g_m2);
vdma_addr_diff <= vdma_addr_diff_s[8:0];
if (vdma_addr_diff >= RDY_THRESHOLD_HI) begin
vdma_ready <= 1'b0;
end else if (vdma_addr_diff <= RDY_THRESHOLD_LO) begin
vdma_ready <= 1'b1;
end
if (vdma_addr_diff > BUF_THRESHOLD_HI) begin
vdma_almost_full <= 1'b1;
end else begin
vdma_almost_full <= 1'b0;
end
if (vdma_addr_diff < BUF_THRESHOLD_LO) begin
vdma_almost_empty <= 1'b1;
end else begin
vdma_almost_empty <= 1'b0;
end
vdma_ovf <= vdma_ovf_s;
vdma_unf <= vdma_unf_s;
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,420 @@
library ieee;
use ieee.std_logic_1164.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
library work;
use work.i2s_controller;
library work;
use work.axi_streaming_dma_rx_fifo;
use work.axi_streaming_dma_tx_fifo;
use work.pl330_dma_fifo;
use work.axi_ctrlif;
entity axi_i2s_adi is
generic
(
-- ADD USER GENERICS BELOW THIS LINE ---------------
C_SLOT_WIDTH : integer := 24;
C_LRCLK_POL : integer := 0; -- LRCLK Polarity (0 - Falling edge, 1 - Rising edge)
C_BCLK_POL : integer := 0; -- BCLK Polarity (0 - Falling edge, 1 - Rising edge)
-- ADD USER GENERICS ABOVE THIS LINE ---------------
-- DO NOT EDIT BELOW THIS LINE ---------------------
-- Bus protocol parameters, do not add to or delete
C_S_AXI_DATA_WIDTH : integer := 32;
C_S_AXI_ADDR_WIDTH : integer := 32;
C_S_AXI_MIN_SIZE : std_logic_vector := X"000001FF";
C_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_HIGHADDR : std_logic_vector := X"00000000";
C_FAMILY : string := "virtex6";
-- DO NOT EDIT ABOVE THIS LINE ---------------------
C_DMA_TYPE : integer := 0;
C_NUM_CH : integer := 1;
C_HAS_TX : integer := 1;
C_HAS_RX : integer := 1
);
port
(
-- Serial Data interface
DATA_CLK_I : in std_logic;
BCLK_O : out std_logic_vector(C_NUM_CH - 1 downto 0);
LRCLK_O : out std_logic_vector(C_NUM_CH - 1 downto 0);
SDATA_O : out std_logic_vector(C_NUM_CH - 1 downto 0);
SDATA_I : in std_logic_vector(C_NUM_CH - 1 downto 0);
-- AXI Streaming DMA TX interface
S_AXIS_ACLK : in std_logic;
S_AXIS_ARESETN : in std_logic;
S_AXIS_TREADY : out std_logic;
S_AXIS_TDATA : in std_logic_vector(31 downto 0);
S_AXIS_TLAST : in std_logic;
S_AXIS_TVALID : in std_logic;
-- AXI Streaming DMA RX interface
M_AXIS_ACLK : in std_logic;
M_AXIS_TREADY : in std_logic;
M_AXIS_TDATA : out std_logic_vector(31 downto 0);
M_AXIS_TLAST : out std_logic;
M_AXIS_TVALID : out std_logic;
M_AXIS_TKEEP : out std_logic_vector(3 downto 0);
--PL330 DMA TX interface
DMA_REQ_TX_ACLK : in std_logic;
DMA_REQ_TX_RSTN : in std_logic;
DMA_REQ_TX_DAVALID : in std_logic;
DMA_REQ_TX_DATYPE : in std_logic_vector(1 downto 0);
DMA_REQ_TX_DAREADY : out std_logic;
DMA_REQ_TX_DRVALID : out std_logic;
DMA_REQ_TX_DRTYPE : out std_logic_vector(1 downto 0);
DMA_REQ_TX_DRLAST : out std_logic;
DMA_REQ_TX_DRREADY : in std_logic;
-- PL330 DMA RX interface
DMA_REQ_RX_ACLK : in std_logic;
DMA_REQ_RX_RSTN : in std_logic;
DMA_REQ_RX_DAVALID : in std_logic;
DMA_REQ_RX_DATYPE : in std_logic_vector(1 downto 0);
DMA_REQ_RX_DAREADY : out std_logic;
DMA_REQ_RX_DRVALID : out std_logic;
DMA_REQ_RX_DRTYPE : out std_logic_vector(1 downto 0);
DMA_REQ_RX_DRLAST : out std_logic;
DMA_REQ_RX_DRREADY : in std_logic;
-- AXI bus interface
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_RREADY : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_WREADY : inout std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : inout std_logic;
S_AXI_AWREADY : inout std_logic
);
end entity axi_i2s_adi;
architecture Behavioral of axi_i2s_adi is
------------------------------------------
-- Signals for user logic slave model s/w accessible register example
------------------------------------------
signal i2s_reset : std_logic;
signal tx_fifo_reset : std_logic;
signal tx_enable : Boolean;
signal tx_data : std_logic_vector(C_SLOT_WIDTH - 1 downto 0);
signal tx_ack : std_logic;
signal tx_stb : std_logic;
signal rx_enable : Boolean;
signal rx_fifo_reset : std_logic;
signal rx_data : std_logic_vector(C_SLOT_WIDTH - 1 downto 0);
signal rx_ack : std_logic;
signal rx_stb : std_logic;
signal const_1 : std_logic;
signal bclk_div_rate : natural range 0 to 255;
signal lrclk_div_rate : natural range 0 to 255;
signal period_len : integer range 0 to 65535;
signal I2S_RESET_REG : std_logic_vector(31 downto 0);
signal I2S_CONTROL_REG : std_logic_vector(31 downto 0);
signal I2S_CLK_CONTROL_REG : std_logic_vector(31 downto 0);
signal PERIOD_LEN_REG : std_logic_vector(31 downto 0);
constant FIFO_AWIDTH : integer := integer(ceil(log2(real(C_NUM_CH * 8))));
-- Audio samples FIFO
constant RAM_ADDR_WIDTH : integer := 7;
type RAM_TYPE is array (0 to (2**RAM_ADDR_WIDTH - 1)) of std_logic_vector(31 downto 0);
-- RX FIFO signals
signal audio_fifo_rx : RAM_TYPE;
signal audio_fifo_rx_wr_addr : integer range 0 to 2**RAM_ADDR_WIDTH-1;
signal audio_fifo_rx_rd_addr : integer range 0 to 2**RAM_ADDR_WIDTH-1;
signal tvalid : std_logic := '0';
signal rx_tlast : std_logic;
signal drain_tx_dma : std_logic;
signal rx_sample : std_logic_vector(23 downto 0);
signal wr_data : std_logic_vector(31 downto 0);
signal rd_data : std_logic_vector(31 downto 0);
signal wr_addr : integer range 0 to 11;
signal rd_addr : integer range 0 to 11;
signal wr_stb : std_logic;
signal rd_ack : std_logic;
signal tx_fifo_stb : std_logic;
signal rx_fifo_ack : std_logic;
signal cnt : integer range 0 to 2**16-1;
begin
const_1 <= '1';
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
cnt <= 0;
else
cnt <= (cnt + 1) mod 2**16;
end if;
end if;
end process;
streaming_dma_tx_gen: if C_DMA_TYPE = 0 and C_HAS_TX = 1 generate
tx_fifo : entity axi_streaming_dma_tx_fifo
generic map(
RAM_ADDR_WIDTH => FIFO_AWIDTH,
FIFO_DWIDTH => 24
)
port map(
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => tx_fifo_reset,
enable => tx_enable,
S_AXIS_ACLK => S_AXIS_ACLK,
S_AXIS_TREADY => S_AXIS_TREADY,
S_AXIS_TDATA => S_AXIS_TDATA(31 downto 8),
S_AXIS_TLAST => S_AXIS_TLAST,
S_AXIS_TVALID => S_AXIS_TVALID,
out_stb => tx_stb,
out_ack => tx_ack,
out_data => tx_data
);
end generate;
streaming_dma_rx_gen: if C_DMA_TYPE = 0 and C_HAS_RX = 1 generate
rx_fifo : entity axi_streaming_dma_rx_fifo
generic map(
RAM_ADDR_WIDTH => FIFO_AWIDTH,
FIFO_DWIDTH => 24
)
port map(
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => tx_fifo_reset,
enable => tx_enable,
period_len => period_len,
in_stb => rx_stb,
in_ack => rx_ack,
in_data => rx_data,
M_AXIS_ACLK => M_AXIS_ACLK,
M_AXIS_TREADY => M_AXIS_TREADY,
M_AXIS_TDATA => M_AXIS_TDATA(31 downto 8),
M_AXIS_TLAST => M_AXIS_TLAST,
M_AXIS_TVALID => M_AXIS_TVALID,
M_AXIS_TKEEP => M_AXIS_TKEEP
);
M_AXIS_TDATA(7 downto 0) <= (others => '0');
end generate;
pl330_dma_tx_gen: if C_DMA_TYPE = 1 and C_HAS_TX = 1 generate
tx_fifo_stb <= '1' when wr_addr = 11 and wr_stb = '1' else '0';
tx_fifo: entity pl330_dma_fifo
generic map(
RAM_ADDR_WIDTH => FIFO_AWIDTH,
FIFO_DWIDTH => 24,
FIFO_DIRECTION => 0
)
port map (
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => tx_fifo_reset,
enable => tx_enable,
in_data => wr_data(31 downto 8),
in_stb => tx_fifo_stb,
out_ack => tx_ack,
out_stb => tx_stb,
out_data => tx_data,
dclk => DMA_REQ_TX_ACLK,
dresetn => DMA_REQ_TX_RSTN,
davalid => DMA_REQ_TX_DAVALID,
daready => DMA_REQ_TX_DAREADY,
datype => DMA_REQ_TX_DATYPE,
drvalid => DMA_REQ_TX_DRVALID,
drready => DMA_REQ_TX_DRREADY,
drtype => DMA_REQ_TX_DRTYPE,
drlast => DMA_REQ_TX_DRLAST
);
end generate;
pl330_dma_rx_gen: if C_DMA_TYPE = 1 and C_HAS_RX = 1 generate
rx_fifo_ack <= '1' when rd_addr = 10 and rd_ack = '1' else '0';
rx_fifo: entity pl330_dma_fifo
generic map(
RAM_ADDR_WIDTH => FIFO_AWIDTH,
FIFO_DWIDTH => 24,
FIFO_DIRECTION => 1
)
port map (
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => rx_fifo_reset,
enable => rx_enable,
in_ack => rx_ack,
in_stb => rx_stb,
in_data => rx_data,
out_data => rx_sample,
out_ack => rx_fifo_ack,
dclk => DMA_REQ_RX_ACLK,
dresetn => DMA_REQ_RX_RSTN,
davalid => DMA_REQ_RX_DAVALID,
daready => DMA_REQ_RX_DAREADY,
datype => DMA_REQ_RX_DATYPE,
drvalid => DMA_REQ_RX_DRVALID,
drready => DMA_REQ_RX_DRREADY,
drtype => DMA_REQ_RX_DRTYPE,
drlast => DMA_REQ_RX_DRLAST
);
end generate;
ctrl : entity i2s_controller
generic map (
C_SLOT_WIDTH => C_SLOT_WIDTH,
C_BCLK_POL => C_BCLK_POL,
C_LRCLK_POL => C_LRCLK_POL,
C_NUM_CH => C_NUM_CH,
C_HAS_TX => C_HAS_TX,
C_HAS_RX => C_HAS_RX
)
port map (
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
data_clk => DATA_CLK_I,
BCLK_O => BCLK_O,
LRCLK_O => LRCLK_O,
SDATA_O => SDATA_O,
SDATA_I => SDATA_I,
tx_enable => tx_enable,
tx_ack => tx_ack,
tx_stb => tx_stb,
tx_data => tx_data,
rx_enable => rx_enable,
rx_ack => rx_ack,
rx_stb => rx_stb,
rx_data => rx_data,
bclk_div_rate => bclk_div_rate,
lrclk_div_rate => lrclk_div_rate
);
i2s_reset <= I2S_RESET_REG(0);
tx_fifo_reset <= I2S_RESET_REG(1);
rx_fifo_reset <= I2S_RESET_REG(2);
tx_enable <= I2S_CONTROL_REG(0) = '1';
rx_enable <= I2S_CONTROL_REG(1) = '1';
bclk_div_rate <= to_integer(unsigned(I2S_CLK_CONTROL_REG(7 downto 0)));
lrclk_div_rate <= to_integer(unsigned(I2S_CLK_CONTROL_REG(23 downto 16)));
period_len <= to_integer(unsigned(PERIOD_LEN_REG(15 downto 0)));
ctrlif: entity axi_ctrlif
generic map (
C_S_AXI_ADDR_WIDTH => C_S_AXI_ADDR_WIDTH,
C_S_AXI_DATA_WIDTH => C_S_AXI_DATA_WIDTH,
C_NUM_REG => 12
)
port map(
S_AXI_ACLK => S_AXI_ACLK,
S_AXI_ARESETN => S_AXI_ARESETN,
S_AXI_AWADDR => S_AXI_AWADDR,
S_AXI_AWVALID => S_AXI_AWVALID,
S_AXI_WDATA => S_AXI_WDATA,
S_AXI_WSTRB => S_AXI_WSTRB,
S_AXI_WVALID => S_AXI_WVALID,
S_AXI_BREADY => S_AXI_BREADY,
S_AXI_ARADDR => S_AXI_ARADDR,
S_AXI_ARVALID => S_AXI_ARVALID,
S_AXI_RREADY => S_AXI_RREADY,
S_AXI_ARREADY => S_AXI_ARREADY,
S_AXI_RDATA => S_AXI_RDATA,
S_AXI_RRESP => S_AXI_RRESP,
S_AXI_RVALID => S_AXI_RVALID,
S_AXI_WREADY => S_AXI_WREADY,
S_AXI_BRESP => S_AXI_BRESP,
S_AXI_BVALID => S_AXI_BVALID,
S_AXI_AWREADY => S_AXI_AWREADY,
rd_addr => rd_addr,
rd_data => rd_data,
rd_ack => rd_ack,
rd_stb => const_1,
wr_addr => wr_addr,
wr_data => wr_data,
wr_ack => const_1,
wr_stb => wr_stb
);
process(rd_addr)
begin
case rd_addr is
when 1 => rd_data <= I2S_CONTROL_REG and x"00000003";
when 2 => rd_data <= I2S_CLK_CONTROL_REG and x"00ff00ff";
when 6 => rd_data <= PERIOD_LEN_REG and x"0000ffff";
when 10 => rd_data <= rx_sample & std_logic_vector(to_unsigned(cnt, 8));
when others => rd_data <= (others => '0');
end case;
end process;
process(S_AXI_ACLK) is
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
I2S_RESET_REG <= (others => '0');
I2S_CONTROL_REG <= (others => '0');
I2S_CLK_CONTROL_REG <= (others => '0');
PERIOD_LEN_REG <= (others => '0');
else
-- Auto-clear the Reset Register bits
I2S_RESET_REG(0) <= '0';
I2S_RESET_REG(1) <= '0';
I2S_RESET_REG(2) <= '0';
if wr_stb = '1' then
case wr_addr is
when 0 => I2S_RESET_REG <= wr_data;
when 1 => I2S_CONTROL_REG <= wr_data;
when 2 => I2S_CLK_CONTROL_REG <= wr_data;
when 6 => PERIOD_LEN_REG <= wr_data;
when others => null;
end case;
end if;
end if;
end if;
end process;
end Behavioral;

View File

@ -0,0 +1,80 @@
# ip
source ../scripts/adi_ip.tcl
adi_ip_create axi_i2s_adi
adi_ip_files axi_i2s_adi [list \
"../common/axi_ctrlif.vhd" \
"../common/axi_streaming_dma_tx_fifo.vhd" \
"../common/axi_streaming_dma_rx_fifo.vhd" \
"../common/pl330_dma_fifo.vhd" \
"../common/dma_fifo.vhd" \
"i2s_controller.vhd" \
"i2s_rx.vhd" \
"i2s_tx.vhd" \
"i2s_clkgen.vhd" \
"fifo_synchronizer.vhd" \
"axi_i2s_adi.vhd" ]
adi_ip_properties_lite axi_i2s_adi
adi_add_bus "M_AXIS" "axis" "master" \
[list {"M_AXIS_ACLK" "ACLK"} \
{"M_AXIS_TREADY" "TREADY"} \
{"M_AXIS_TVALID" "VALID"} \
{"M_AXIS_TDATA" "TDATA"} \
{"M_AXIS_TLAST" "TLAST"} \
{"M_AXIS_TKEEP" "TKEEP"} ]
adi_add_bus "S_AXIS" "axis" "slave" \
[list {"S_AXIS_ACLK" "ACLK"} \
{"S_AXIS_ARESETN" "ARESETN"} \
{"S_AXIS_TREADY" "TREADY"} \
{"S_AXIS_TVALID" "VALID"} \
{"S_AXIS_TDATA" "TDATA"} \
{"S_AXIS_TLAST" "TLAST"} ]
adi_add_bus "DMA_ACK_RX" "axis" "slave" \
[list {"DMA_REQ_RX_DAVALID" "TVALID"} \
{"DMA_REQ_RX_DAREADY" "TREADY"} \
{"DMA_REQ_RX_DATYPE" "TUSER"} ]
adi_add_bus "DMA_REQ_RX" "axis" "master" \
[list {"DMA_REQ_RX_DRVALID" "TVALID"} \
{"DMA_REQ_RX_DRREADY" "TREADY"} \
{"DMA_REQ_RX_DRTYPE" "TUSER"} \
{"DMA_REQ_RX_DRLAST" "TLAST"} ]
adi_add_bus "DMA_ACK_TX" "axis" "slave" \
[list {"DMA_REQ_TX_DAVALID" "TVALID"} \
{"DMA_REQ_TX_DAREADY" "TREADY"} \
{"DMA_REQ_TX_DATYPE" "TUSER"} ]
adi_add_bus "DMA_REQ_TX" "axis" "master" \
[list {"DMA_REQ_TX_DRVALID" "TVALID"} \
{"DMA_REQ_TX_DRREADY" "TREADY"} \
{"DMA_REQ_TX_DRTYPE" "TUSER"} \
{"DMA_REQ_TX_DRLAST" "TLAST"} ]
adi_set_bus_dependency "S_AXIS" "S_AXIS" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 0)"
adi_set_bus_dependency "M_AXIS" "M_AXIS" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 0)"
adi_set_bus_dependency "DMA_ACK_TX" "DMA_REQ_TX_DA" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_bus_dependency "DMA_REQ_TX" "DMA_REQ_TX_DR" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_TX_ACLK" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_TX_RSTN" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_bus_dependency "DMA_ACK_RX" "DMA_REQ_RX_DA" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_bus_dependency "DMA_REQ_RX" "DMA_REQ_RX_DR" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_RX_ACLK" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_RX_RSTN" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,108 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity fifo_synchronizer is
generic (
DEPTH : integer := 4;
WIDTH : integer := 2
);
port (
resetn : in std_logic;
in_clk : in std_logic;
in_data : in std_logic_vector(WIDTH - 1 downto 0);
in_tick : in std_logic;
out_clk : in std_logic;
out_data : out std_logic_vector(WIDTH - 1 downto 0);
out_tick : out std_logic
);
end fifo_synchronizer;
architecture impl of fifo_synchronizer is
type DATA_SYNC_FIFO_TYPE is array (0 to DEPTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
signal fifo: DATA_SYNC_FIFO_TYPE;
signal rd_addr : natural range 0 to DEPTH - 1;
signal wr_addr : natural range 0 to DEPTH - 1;
signal tick : std_logic;
signal tick_d1 : std_logic;
signal tick_d2 : std_logic;
begin
process (in_clk)
begin
if rising_edge(in_clk) then
if resetn = '0' then
wr_addr <= 0;
tick <= '0';
else
if in_tick = '1' then
fifo(wr_addr) <= in_data;
wr_addr <= (wr_addr + 1) mod DEPTH;
tick <= not tick;
end if;
end if;
end if;
end process;
process (out_clk)
begin
if rising_edge(out_clk) then
if resetn = '0' then
rd_addr <= 0;
tick_d1 <= '0';
tick_d2 <= '0';
else
tick_d1 <= tick;
tick_d2 <= tick_d1;
out_tick <= tick_d1 xor tick_d2;
if (tick_d1 xor tick_d2) = '1' then
rd_addr <= (rd_addr + 1) mod DEPTH;
out_data <= fifo(rd_addr);
end if;
end if;
end if;
end process;
end;

View File

@ -0,0 +1,133 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity i2s_clkgen is
port(
clk : in std_logic; -- System clock
resetn : in std_logic; -- System reset
enable : in Boolean ; -- Enable clockgen
tick : in std_logic;
bclk_div_rate : in natural range 0 to 255;
lrclk_div_rate : in natural range 0 to 255;
bclk : out std_logic; -- Bit Clock
lrclk : out std_logic; -- Frame Clock
channel_sync : out std_logic;
frame_sync : out std_logic
);
end i2s_clkgen;
architecture Behavioral of i2s_clkgen is
signal reset_int : Boolean;
signal prev_bclk_div_rate : natural range 0 to 255;
signal prev_lrclk_div_rate : natural range 0 to 255;
signal bclk_count : natural range 0 to 255;
signal lrclk_count : natural range 0 to 255;
signal bclk_int : std_logic;
signal lrclk_int : std_logic;
signal lrclk_tick : Boolean;
begin
reset_int <= resetn = '0' or not enable;
bclk <= bclk_int;
lrclk <= lrclk_int;
-----------------------------------------------------------------------------------
-- Serial clock generation BCLK_O
-----------------------------------------------------------------------------------
bclk_gen: process(clk)
begin
if rising_edge(clk) then
prev_bclk_div_rate <= bclk_div_rate;
if reset_int then -- or (bclk_div_rate /= prev_bclk_div_rate) then
bclk_int <= '1';
bclk_count <= bclk_div_rate;
else
if tick = '1' then
if bclk_count = bclk_div_rate then
bclk_count <= 0;
bclk_int <= not bclk_int;
else
bclk_count <= bclk_count + 1;
end if;
end if;
end if;
end if;
end process bclk_gen;
lrclk_tick <= tick = '1' and bclk_count = bclk_div_rate and bclk_int = '1';
channel_sync <= '1' when lrclk_count = 1 else '0';
frame_sync <= '1' when lrclk_count = 1 and lrclk_int = '0' else '0';
-----------------------------------------------------------------------------------
-- Frame clock generator LRCLK_O
-----------------------------------------------------------------------------------
lrclk_gen: process(clk)
begin
if rising_edge(clk) then
prev_lrclk_div_rate <= lrclk_div_rate;
-- Reset
if reset_int then -- or lrclk_div_rate /= prev_lrclk_div_rate then
lrclk_int <= '1';
lrclk_count <= lrclk_div_rate;
else
if lrclk_tick then
if lrclk_count = lrclk_div_rate then
lrclk_count <= 0;
lrclk_int <= not lrclk_int;
else
lrclk_count <= lrclk_count + 1;
end if;
end if;
end if;
end if;
end process lrclk_gen;
end Behavioral;

View File

@ -0,0 +1,285 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.fifo_synchronizer;
use work.i2s_clkgen;
use work.i2s_tx;
use work.i2s_rx;
entity i2s_controller is
generic(
C_SLOT_WIDTH : integer := 24; -- Width of one Slot
C_BCLK_POL : integer := 0; -- BCLK Polarity (0 - Falling edge, 1 - Rising edge)
C_LRCLK_POL : integer := 0; -- LRCLK Polarity (0 - Falling edge, 1 - Rising edge)
C_NUM_CH : integer := 1;
C_HAS_TX : integer := 1;
C_HAS_RX : integer := 1
);
port(
clk : in std_logic; -- System clock
resetn : in std_logic; -- System reset
data_clk : in std_logic; -- Data clock should be less than clk / 4
BCLK_O : out std_logic_vector(C_NUM_CH - 1 downto 0); -- Bit Clock
LRCLK_O : out std_logic_vector(C_NUM_CH - 1 downto 0); -- Frame Clock
SDATA_O : out std_logic_vector(C_NUM_CH - 1 downto 0); -- Serial Data Output
SDATA_I : in std_logic_vector(C_NUM_CH - 1 downto 0); -- Serial Data Input
tx_enable : in Boolean; -- Enable TX
tx_ack : out std_logic; -- Request new Slot Data
tx_stb : in std_logic; -- Request new Slot Data
tx_data : in std_logic_vector(C_SLOT_WIDTH-1 downto 0); -- Slot Data in
rx_enable : in Boolean; -- Enable RX
rx_ack : in std_logic;
rx_stb : out std_logic; -- Valid Slot Data
rx_data : out std_logic_vector(C_SLOT_WIDTH-1 downto 0); -- Slot Data out
-- Runtime parameter
bclk_div_rate : in natural range 0 to 255;
lrclk_div_rate : in natural range 0 to 255
);
end i2s_controller;
architecture Behavioral of i2s_controller is
constant NUM_TX : integer := C_HAS_TX * C_NUM_CH;
constant NUM_RX : integer := C_HAS_RX * C_NUM_CH;
signal enable : Boolean;
signal tick : std_logic;
signal tick_d1 : std_logic;
signal tick_d2 : std_logic;
signal BCLK_O_int : std_logic;
signal LRCLK_O_int : std_logic;
signal tx_bclk : std_logic;
signal tx_lrclk : std_logic;
signal tx_sdata : std_logic_vector(C_NUM_CH - 1 downto 0);
signal tx_tick : std_logic;
signal tx_channel_sync : std_logic;
signal tx_frame_sync : std_logic;
signal const_1 : std_logic;
signal bclk_tick : std_logic;
signal rx_bclk : std_logic;
signal rx_lrclk : std_logic;
signal rx_sdata : std_logic_vector(NUM_RX - 1 downto 0);
signal rx_channel_sync : std_logic;
signal rx_frame_sync : std_logic;
signal tx_sync_fifo_out : std_logic_vector(3 + NUM_TX downto 0);
signal tx_sync_fifo_in : std_logic_vector(3 + NUM_TX downto 0);
signal rx_sync_fifo_out : std_logic_vector(3 + NUM_RX downto 0);
signal rx_sync_fifo_in : std_logic_vector(3 + NUM_RX downto 0);
begin
enable <= rx_enable or tx_enable;
const_1 <= '1';
-- Generate tick signal in the DATA_CLK_I domain
process (data_clk)
begin
if rising_edge(data_clk) then
if resetn = '0' then
tick <= '0';
else
tick <= not tick;
end if;
end if;
end process;
process (clk)
begin
if rising_edge(clk) then
if resetn = '0' then
tick_d1 <= '0';
tick_d2 <= '0';
else
tick_d1 <= tick;
tick_d2 <= tick_d1;
end if;
end if;
end process;
tx_tick <= tick_d2 xor tick_d1;
tx_sync_fifo_in(0) <= tx_channel_sync;
tx_sync_fifo_in(1) <= tx_frame_sync;
tx_sync_fifo_in(2) <= tx_bclk;
tx_sync_fifo_in(3) <= tx_lrclk;
tx_sync_fifo_in(3 + NUM_TX downto 4) <= tx_sdata;
process (data_clk)
begin
if rising_edge(data_clk) then
if resetn = '0' then
BCLK_O <= (others => '1');
LRCLK_O <= (others => '1');
SDATA_O <= (others => '0');
else
if C_BCLK_POL = 0 then
BCLK_O <= (others => tx_sync_fifo_out(2));
else
BCLK_O <= (others => not tx_sync_fifo_out(2));
end if;
if C_LRCLK_POL = 0 then
LRCLK_O <= (others => tx_sync_fifo_out(3));
else
LRCLK_O <= (others => not tx_sync_fifo_out(3));
end if;
if C_HAS_TX = 1 then
SDATA_O <= tx_sync_fifo_out(3 + NUM_TX downto 4);
end if;
if C_HAS_RX = 1 then
rx_sync_fifo_in(3 downto 0) <= tx_sync_fifo_out(3 downto 0);
rx_sync_fifo_in(3 + NUM_RX downto 4) <= SDATA_I;
end if;
end if;
end if;
end process;
tx_sync: entity fifo_synchronizer
generic map (
DEPTH => 4,
WIDTH => NUM_TX + 4
)
port map (
resetn => resetn,
in_clk => clk,
in_data => tx_sync_fifo_in,
in_tick => tx_tick,
out_clk => data_clk,
out_data => tx_sync_fifo_out
);
clkgen: entity i2s_clkgen
port map(
clk => clk,
resetn => resetn,
enable => enable,
tick => tx_tick,
bclk_div_rate => bclk_div_rate,
lrclk_div_rate => lrclk_div_rate,
channel_sync => tx_channel_sync,
frame_sync => tx_frame_sync,
bclk => tx_bclk,
lrclk => tx_lrclk
);
tx_gen: if C_HAS_TX = 1 generate
tx: entity i2s_tx
generic map (
C_SLOT_WIDTH => C_SLOT_WIDTH,
C_NUM => NUM_TX
)
port map (
clk => clk,
resetn => resetn,
enable => tx_enable,
channel_sync => tx_channel_sync,
frame_sync => tx_frame_sync,
bclk => tx_bclk,
sdata => tx_sdata,
ack => tx_ack,
stb => tx_stb,
data => tx_data
);
end generate;
rx_gen: if C_HAS_RX = 1 generate
rx: entity i2s_rx
generic map (
C_SLOT_WIDTH => C_SLOT_WIDTH,
C_NUM => NUM_RX
)
port map (
clk => clk,
resetn => resetn,
enable => rx_enable,
channel_sync => rx_channel_sync,
frame_sync => rx_frame_sync,
bclk => rx_bclk,
sdata => rx_sdata,
ack => rx_ack,
stb => rx_stb,
data => rx_data
);
rx_channel_sync <= rx_sync_fifo_out(0);
rx_frame_sync <= rx_sync_fifo_out(1);
rx_bclk <= rx_sync_fifo_out(2);
rx_lrclk <= rx_sync_fifo_out(3);
rx_sdata <= rx_sync_fifo_out(3 + NUM_RX downto 4);
rx_sync: entity fifo_synchronizer
generic map (
DEPTH => 4,
WIDTH => NUM_RX + 4
)
port map (
resetn => resetn,
in_clk => data_clk,
in_data => rx_sync_fifo_in,
in_tick => const_1,
out_clk => clk,
out_data => rx_sync_fifo_out
);
end generate;
end Behavioral;

View File

@ -0,0 +1,180 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2s_rx is
generic(
C_SLOT_WIDTH : integer := 24; -- Width of one Slot
C_NUM : integer := 1
);
port(
clk : in std_logic; -- System clock
resetn : in std_logic; -- System reset
enable : in Boolean; -- Enable RX
bclk : in std_logic; -- Bit Clock
channel_sync : in std_logic; -- Channel Sync
frame_sync : in std_logic; -- Frame Sync
sdata : in std_logic_vector(C_NUM - 1 downto 0); -- Serial Data Output
stb : out std_logic; -- Data available
ack : in std_logic; -- Data has been consumed
data : out std_logic_vector(C_SLOT_WIDTH-1 downto 0) -- Slot Data in
);
end i2s_rx;
architecture Behavioral of i2s_rx is
type mem is array (0 to C_NUM - 1) of std_logic_vector(31 downto 0);
type mem_latched is array (0 to C_NUM - 1) of std_logic_vector(C_SLOT_WIDTH - 1 downto 0);
signal data_int : mem;
signal data_latched : mem_latched;
signal reset_int : Boolean;
signal enable_int : Boolean;
signal bit_sync : std_logic;
signal channel_sync_int : std_logic;
signal frame_sync_int : std_logic;
signal bclk_d1 : std_logic;
type sequencer_state_type is (IDLE, ACTIVE);
signal sequencer_state : sequencer_state_type;
signal seq : natural range 0 to C_NUM - 1;
signal ovf_frame_cnt : natural range 0 to 1;
begin
reset_int <= (resetn = '0') or not enable;
process (clk)
begin
if rising_edge(clk) then
if resetn = '0' then
bclk_d1 <= '0';
else
bclk_d1 <= bclk;
end if;
end if;
end process;
bit_sync <= (bclk xor bclk_d1) and bclk;
channel_sync_int <= channel_sync and bit_sync;
frame_sync_int <= frame_sync and bit_sync;
stb <= '1' when sequencer_state = ACTIVE else '0';
sequencer: process (clk)
begin
if rising_edge(clk) then
if reset_int or not enable_int then
sequencer_state <= IDLE;
ovf_frame_cnt <= 0;
seq <= 0;
else
case sequencer_state is
when IDLE =>
if channel_sync_int = '1' then
if ovf_frame_cnt = 0 then
sequencer_state <= ACTIVE;
else
ovf_frame_cnt <= (ovf_frame_cnt + 1) mod 2;
end if;
end if;
when ACTIVE =>
-- The unlikely event the last ack came in in the same clock
-- cyclce as the channel sync signal will still be treated
-- as an overflow. This keeps the logic simple
if ack = '1' then
if seq = C_NUM - 1 then
sequencer_state <= IDLE;
seq <= 0;
else
seq <= seq + 1;
end if;
end if;
if channel_sync_int = '1' then
ovf_frame_cnt <= (ovf_frame_cnt + 1) mod 2;
end if;
end case;
end if;
end if;
end process;
data <= data_latched(seq);
gen: for i in 0 to C_NUM - 1 generate
unserialize_data: process(clk)
begin
if rising_edge(clk) then
if reset_int then
data_int(i) <= (others => '0');
elsif bit_sync = '1' then
if channel_sync = '1' then
if sequencer_state = IDLE then
data_latched(i) <= data_int(i)(31 downto 32 - C_SLOT_WIDTH);
-- data_latched(i) <= data_int(i)(31 downto 32 -
-- C_SLOT_WIDTH + 8) &
-- std_logic_vector(to_unsigned(i+1,8));
end if;
end if;
data_int(i) <= data_int(i)(30 downto 0) & sdata(i);
end if;
end if;
end process unserialize_data;
end generate;
enable_sync: process (clk)
begin
if rising_edge(clk) then
if reset_int then
enable_int <= False;
else
if enable and frame_sync_int = '1' then
enable_int <= True;
elsif not enable then
enable_int <= False;
end if;
end if;
end if;
end process enable_sync;
end Behavioral;

View File

@ -0,0 +1,134 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
entity i2s_tx is
generic(
C_SLOT_WIDTH : integer := 24; -- Width of one Slot
C_NUM : integer := 1
);
port(
clk : in std_logic; -- System clock
resetn : in std_logic; -- System reset
enable : in Boolean; -- Enable TX
bclk : in std_logic; -- Bit Clock
channel_sync : in std_logic; -- Channel Sync
frame_sync : in std_logic; -- Frame Sync
sdata : out std_logic_vector(C_NUM - 1 downto 0); -- Serial Data Output
ack : out std_logic; -- Request new Slot Data
stb : in std_logic; -- Request new Slot Data
data : in std_logic_vector(C_SLOT_WIDTH-1 downto 0) -- Slot Data in
);
end i2s_tx;
architecture Behavioral of i2s_tx is
type mem is array (0 to C_NUM - 1) of std_logic_vector(31 downto 0);
signal data_int : mem;
signal reset_int : Boolean;
signal enable_int : Boolean;
signal bit_sync : std_logic;
signal channel_sync_int : std_logic;
signal frame_sync_int : std_logic;
signal channel_sync_int_d1 : std_logic;
signal bclk_d1 : std_logic;
begin
reset_int <= resetn = '0' or not enable;
process (clk)
begin
if rising_edge(clk) then
if resetn = '0' then
bclk_d1 <= '0';
channel_sync_int_d1 <= '0';
else
bclk_d1 <= bclk;
channel_sync_int_d1 <= channel_sync_int;
end if;
end if;
end process;
bit_sync <= (bclk xor bclk_d1) and not bclk;
channel_sync_int <= channel_sync and bit_sync;
frame_sync_int <= frame_sync and bit_sync;
ack <= '1' when channel_sync_int_d1 = '1' and enable_int else '0';
gen: for i in 0 to C_NUM - 1 generate
serialize_data: process(clk)
begin
if rising_edge(clk) then
if reset_int then
data_int(i)(31 downto 0) <= (others => '0');
elsif bit_sync = '1' then
if channel_sync_int = '1' then
data_int(i)(31 downto 32-C_SLOT_WIDTH) <= data;
data_int(i)(31-C_SLOT_WIDTH downto 0) <= (others => '0');
else
data_int(i) <= data_int(i)(30 downto 0) & '0';
end if;
end if;
end if;
end process serialize_data;
sdata(i) <= data_int(i)(31) when enable_int else '0';
end generate;
enable_sync: process (clk)
begin
if rising_edge(clk) then
if reset_int then
enable_int <= False;
else
if enable and frame_sync_int = '1' and stb = '1' then
enable_int <= True;
elsif not enable then
enable_int <= False;
end if;
end if;
end if;
end process;
end Behavioral;

View File

@ -0,0 +1,308 @@
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Copyright 2011-2013(c) Analog Devices, Inc.
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- andrei.cozma@analog.com (c) Analog Devices Inc.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.tx_package.all;
use work.axi_ctrlif;
use work.axi_streaming_dma_tx_fifo;
use work.pl330_dma_fifo;
entity axi_spdif_tx is
generic (
C_S_AXI_DATA_WIDTH : integer := 32;
C_S_AXI_ADDR_WIDTH : integer := 32;
C_BASEADDR : std_logic_vector := X"FFFFFFFF";
C_HIGHADDR : std_logic_vector := X"00000000";
C_FAMILY : string := "virtex6";
C_DMA_TYPE : integer := 0
);
port (
--SPDIF ports
spdif_data_clk : in std_logic;
spdif_tx_o : out std_logic;
--AXI Lite interface
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_RREADY : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_WREADY : out std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_AWREADY : out std_logic;
--AXI streaming interface
S_AXIS_ACLK : in std_logic;
S_AXIS_ARESETN : in std_logic;
S_AXIS_TREADY : out std_logic;
S_AXIS_TDATA : in std_logic_vector(31 downto 0);
S_AXIS_TLAST : in std_logic;
S_AXIS_TVALID : in std_logic;
--PL330 DMA interface
DMA_REQ_ACLK : in std_logic;
DMA_REQ_RSTN : in std_logic;
DMA_REQ_DAVALID : in std_logic;
DMA_REQ_DATYPE : in std_logic_vector(1 downto 0);
DMA_REQ_DAREADY : out std_logic;
DMA_REQ_DRVALID : out std_logic;
DMA_REQ_DRTYPE : out std_logic_vector(1 downto 0);
DMA_REQ_DRLAST : out std_logic;
DMA_REQ_DRREADY : in std_logic
);
end entity axi_spdif_tx;
------------------------------------------------------------------------------
-- Architecture section
------------------------------------------------------------------------------
architecture IMP of axi_spdif_tx is
------------------------------------------
-- SPDIF signals
------------------------------------------
signal config_reg : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal chstatus_reg : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal chstat_freq : std_logic_vector(1 downto 0);
signal chstat_gstat, chstat_preem, chstat_copy, chstat_audio : std_logic;
signal sample_data_ack : std_logic;
signal sample_data: std_logic_vector(15 downto 0);
signal conf_mode : std_logic_vector(3 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_tinten, conf_txdata, conf_txen : std_logic;
signal channel : std_logic;
signal fifo_data_out : std_logic_vector(31 downto 0);
signal fifo_reset : std_logic;
signal tx_fifo_stb : std_logic;
-- Register access
signal wr_data : std_logic_vector(31 downto 0);
signal rd_data : std_logic_vector(31 downto 0);
signal wr_addr : integer range 0 to 3;
signal rd_addr : integer range 0 to 3;
signal wr_stb : std_logic;
signal rd_ack : std_logic;
begin
fifo_reset <= not conf_txdata;
streaming_dma_gen: if C_DMA_TYPE = 0 generate
fifo: entity axi_streaming_dma_tx_fifo
generic map (
RAM_ADDR_WIDTH => 3,
FIFO_DWIDTH => 32
)
port map (
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => fifo_reset,
enable => conf_txdata = '1',
S_AXIS_ACLK => S_AXIS_ACLK,
S_AXIS_TREADY => S_AXIS_TREADY,
S_AXIS_TDATA => S_AXIS_TDATA,
S_AXIS_TVALID => S_AXIS_TLAST,
S_AXIS_TLAST => S_AXIS_TVALID,
out_ack => channel and sample_data_ack,
out_data => fifo_data_out
);
end generate;
pl330_dma_gen: if C_DMA_TYPE = 1 generate
tx_fifo_stb <= '1' when wr_addr = 3 and wr_stb = '1' else '0';
fifo: entity pl330_dma_fifo
generic map(
RAM_ADDR_WIDTH => 3,
FIFO_DWIDTH => 32,
FIFO_DIRECTION => 0
)
port map (
clk => S_AXI_ACLK,
resetn => S_AXI_ARESETN,
fifo_reset => fifo_reset,
enable => conf_txdata = '1',
in_data => wr_data,
in_stb => tx_fifo_stb,
out_ack => channel and sample_data_ack,
out_data => fifo_data_out,
dclk => DMA_REQ_ACLK,
dresetn => DMA_REQ_RSTN,
davalid => DMA_REQ_DAVALID,
daready => DMA_REQ_DAREADY,
datype => DMA_REQ_DATYPE,
drvalid => DMA_REQ_DRVALID,
drready => DMA_REQ_DRREADY,
drtype => DMA_REQ_DRTYPE,
drlast => DMA_REQ_DRLAST
);
end generate;
sample_data_mux: process (fifo_data_out, channel) is
begin
if channel = '0' then
sample_data <= fifo_data_out(15 downto 0);
else
sample_data <= fifo_data_out(31 downto 16);
end if;
end process;
-- Configuration signals update
conf_mode(3 downto 0) <= config_reg(23 downto 20);
conf_ratio(7 downto 0) <= config_reg(15 downto 8);
conf_tinten <= config_reg(2);
conf_txdata <= config_reg(1);
conf_txen <= config_reg(0);
-- Channel status signals update
chstat_freq(1 downto 0) <= chstatus_reg(7 downto 6);
chstat_gstat <= chstatus_reg(3);
chstat_preem <= chstatus_reg(2);
chstat_copy <= chstatus_reg(1);
chstat_audio <= chstatus_reg(0);
-- Transmit encoder
TENC: tx_encoder
generic map (
DATA_WIDTH => 16
)
port map (
up_clk => S_AXI_ACLK,
data_clk => spdif_data_clk, -- data clock
resetn => S_AXI_ARESETN, -- resetn
conf_mode => conf_mode, -- sample format
conf_ratio => conf_ratio, -- clock divider
conf_txdata => conf_txdata, -- sample data enable
conf_txen => conf_txen, -- spdif signal enable
chstat_freq => chstat_freq, -- sample freq.
chstat_gstat => chstat_gstat, -- generation status
chstat_preem => chstat_preem, -- preemphasis status
chstat_copy => chstat_copy, -- copyright bit
chstat_audio => chstat_audio, -- data format
sample_data => sample_data, -- audio data
sample_data_ack => sample_data_ack, -- sample buffer read
channel => channel, -- which channel should be read
spdif_tx_o => spdif_tx_o -- SPDIF output signal
);
ctrlif: entity axi_ctrlif
generic map (
C_S_AXI_ADDR_WIDTH => C_S_AXI_ADDR_WIDTH,
C_S_AXI_DATA_WIDTH => C_S_AXI_DATA_WIDTH,
C_NUM_REG => 4
)
port map(
S_AXI_ACLK => S_AXI_ACLK,
S_AXI_ARESETN => S_AXI_ARESETN,
S_AXI_AWADDR => S_AXI_AWADDR,
S_AXI_AWVALID => S_AXI_AWVALID,
S_AXI_WDATA => S_AXI_WDATA,
S_AXI_WSTRB => S_AXI_WSTRB,
S_AXI_WVALID => S_AXI_WVALID,
S_AXI_BREADY => S_AXI_BREADY,
S_AXI_ARADDR => S_AXI_ARADDR,
S_AXI_ARVALID => S_AXI_ARVALID,
S_AXI_RREADY => S_AXI_RREADY,
S_AXI_ARREADY => S_AXI_ARREADY,
S_AXI_RDATA => S_AXI_RDATA,
S_AXI_RRESP => S_AXI_RRESP,
S_AXI_RVALID => S_AXI_RVALID,
S_AXI_WREADY => S_AXI_WREADY,
S_AXI_BRESP => S_AXI_BRESP,
S_AXI_BVALID => S_AXI_BVALID,
S_AXI_AWREADY => S_AXI_AWREADY,
rd_addr => rd_addr,
rd_data => rd_data,
rd_ack => rd_ack,
rd_stb => '1',
wr_addr => wr_addr,
wr_data => wr_data,
wr_ack => '1',
wr_stb => wr_stb
);
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
config_reg <= (others => '0');
chstatus_reg <= (others => '0');
else
if wr_stb = '1' then
case wr_addr is
when 0 => config_reg <= wr_data;
when 1 => chstatus_reg <= wr_data;
when others => null;
end case;
end if;
end if;
end if;
end process;
process (rd_addr)
begin
case rd_addr is
when 0 => rd_data <= config_reg;
when 1 => rd_data <= chstatus_reg;
when others => rd_data <= (others => '0');
end case;
end process;
end IMP;

View File

@ -0,0 +1,48 @@
# ip
source ../scripts/adi_ip.tcl
adi_ip_create axi_spdif_tx
adi_ip_files axi_spdif_tx [list \
"../common/axi_ctrlif.vhd" \
"../common/axi_streaming_dma_tx_fifo.vhd" \
"../common/pl330_dma_fifo.vhd" \
"../common/dma_fifo.vhd" \
"tx_package.vhd" \
"tx_encoder.vhd" \
"axi_spdif_tx.vhd" ]
adi_ip_properties_lite axi_spdif_tx
adi_add_bus "S_AXIS" "axis" "slave" \
[list {"S_AXIS_ACLK" "ACLK"} \
{"S_AXIS_ARESETN" "ARESETN"} \
{"S_AXIS_TREADY" "TREADY"} \
{"S_AXIS_TVALID" "VALID"} \
{"S_AXIS_TDATA" "TDATA"} \
{"S_AXIS_TLAST" "TLAST"} ]
adi_add_bus "DMA_ACK" "axis" "slave" \
[list {"DMA_REQ_DAVALID" "TVALID"} \
{"DMA_REQ_DAREADY" "TREADY"} \
{"DMA_REQ_DATYPE" "TUSER"} ]
adi_add_bus "DMA_REQ" "axis" "master" \
[list {"DMA_REQ_DRVALID" "TVALID"} \
{"DMA_REQ_DRREADY" "TREADY"} \
{"DMA_REQ_DRTYPE" "TUSER"} \
{"DMA_REQ_DRLAST" "TLAST"} ]
adi_set_bus_dependency "S_AXIS" "S_AXIS" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 0)"
adi_set_bus_dependency "DMA_ACK" "DMA_REQ_DA" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_bus_dependency "DMA_REQ" "DMA_REQ_DR" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_ACLK" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
adi_set_ports_dependency "DMA_REQ_RSTN" \
"(spirit:decode(id('MODELPARAM_VALUE.C_DMA_TYPE')) = 1)"
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,491 @@
----------------------------------------------------------------------
---- ----
---- WISHBONE SPDIF IP Core ----
---- ----
---- This file is part of the SPDIF project ----
---- http://www.opencores.org/cores/spdif_interface/ ----
---- ----
---- Description ----
---- SPDIF transmitter signal encoder. Reads out samples from the ----
---- sample buffer, assembles frames and subframes and encodes ----
---- serial data as bi-phase mark code. ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Geir Drange, gedra@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2004 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source 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. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tx_encoder is
generic (DATA_WIDTH: integer range 16 to 32 := 32);
port (
up_clk: in std_logic; -- clock
data_clk : in std_logic; -- data clock
resetn : in std_logic; -- resetn
conf_mode: in std_logic_vector(3 downto 0); -- sample format
conf_ratio: in std_logic_vector(7 downto 0); -- clock divider
conf_txdata: in std_logic; -- sample data enable
conf_txen: in std_logic; -- spdif signal enable
chstat_freq: in std_logic_vector(1 downto 0); -- sample freq.
chstat_gstat: in std_logic; -- generation status
chstat_preem: in std_logic; -- preemphasis status
chstat_copy: in std_logic; -- copyright bit
chstat_audio: in std_logic; -- data format
sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data
sample_data_ack: out std_logic; -- sample buffer read
channel: out std_logic;
spdif_tx_o: out std_logic);
end tx_encoder;
architecture rtl of tx_encoder is
signal spdif_clk_en, spdif_out : std_logic;
signal clk_cnt : integer range 0 to 511;
type buf_states is (IDLE, READ_CHA, READ_CHB, CHA_RDY, CHB_RDY);
signal bufctrl : buf_states;
signal cha_samp_ack, chb_samp_ack : std_logic;
type frame_states is (IDLE, BLOCK_START, CHANNEL_A, CHANNEL_B);
signal framest : frame_states;
signal frame_cnt : integer range 0 to 191;
signal bit_cnt, par_cnt : integer range 0 to 31;
signal inv_preamble, toggle, valid : std_logic;
signal def_user_data, def_ch_status : std_logic_vector(191 downto 0);
signal active_user_data, active_ch_status : std_logic_vector(191 downto 0);
signal audio : std_logic_vector(23 downto 0);
signal par_vector : std_logic_vector(26 downto 0);
signal send_audio : std_logic;
signal tick_counter : std_logic;
signal tick_counter_d1 : std_logic;
signal tick_counter_d2 : std_logic;
constant X_PREAMBLE : std_logic_vector(0 to 7) := "11100010";
constant Y_PREAMBLE : std_logic_vector(0 to 7) := "11100100";
constant Z_PREAMBLE : std_logic_vector(0 to 7) := "11101000";
function encode_bit (
signal bit_cnt : integer; -- sub-frame bit position
signal valid : std_logic; -- validity bit
signal frame_cnt : integer; -- frame counter
signal par_cnt : integer; -- parity counter
signal user_data : std_logic_vector(191 downto 0);
signal ch_status : std_logic_vector(191 downto 0);
signal audio : std_logic_vector(23 downto 0);
signal toggle : std_logic;
signal prev_spdif : std_logic) -- prev. value of spdif signal
return std_logic is
variable spdif, next_bit : std_logic;
begin
if bit_cnt > 3 and bit_cnt < 28 then -- audio part
next_bit := audio(bit_cnt - 4);
elsif bit_cnt = 28 then -- validity bit
next_bit := valid;
elsif bit_cnt = 29 then -- user data
next_bit := user_data(frame_cnt);
elsif bit_cnt = 30 then
next_bit := ch_status(frame_cnt); -- channel status
elsif bit_cnt = 31 then
if par_cnt mod 2 = 1 then
next_bit := '1';
else
next_bit := '0';
end if;
end if;
-- bi-phase mark encoding:
if next_bit = '0' then
if toggle = '0' then
spdif := not prev_spdif;
else
spdif := prev_spdif;
end if;
else
spdif := not prev_spdif;
end if;
return(spdif);
end encode_bit;
begin
-- SPDIF clock enable generation. The clock is a fraction of the data clock,
-- determined by the conf_ratio value.
DCLK : process (data_clk)
begin
if rising_edge(data_clk) then
tick_counter <= not tick_counter;
end if;
end process DCLK;
CGEN: process (up_clk)
begin
if rising_edge(up_clk) then
if resetn = '0' or conf_txen = '0' then
clk_cnt <= 0;
tick_counter_d1 <= '0';
tick_counter_d2 <= '0';
spdif_clk_en <= '0';
else
tick_counter_d1 <= tick_counter;
tick_counter_d2 <= tick_counter_d1;
spdif_clk_en <= '0';
if (tick_counter_d1 xor tick_counter_d2) = '1' then
if clk_cnt < to_integer(unsigned(conf_ratio)) then
clk_cnt <= clk_cnt + 1;
else
clk_cnt <= 0;
spdif_clk_en <= '1';
end if;
end if;
end if;
end if;
end process CGEN;
SRD: process (up_clk)
begin
if rising_edge(up_clk) then
if resetn = '0' or conf_txdata = '0' then
bufctrl <= IDLE;
sample_data_ack <= '0';
channel <= '0';
else
case bufctrl is
when IDLE =>
sample_data_ack <= '0';
if conf_txdata = '1' then
bufctrl <= READ_CHA;
sample_data_ack <='1';
end if;
when READ_CHA =>
channel <= '0';
sample_data_ack <= '0';
bufctrl <= CHA_RDY;
when CHA_RDY =>
if cha_samp_ack = '1' then
sample_data_ack <= '1';
bufctrl <= READ_CHB;
end if;
when READ_CHB =>
channel <= '1';
sample_data_ack <= '0';
bufctrl <= CHB_RDY;
when CHB_RDY =>
if chb_samp_ack = '1' then
sample_data_ack <= '1';
bufctrl <= READ_CHA;
end if;
when others =>
bufctrl <= IDLE;
end case;
end if;
end if;
end process SRD;
TXSYNC: process (data_clk)
begin
if (rising_edge(data_clk)) then
if resetn = '0' then
spdif_tx_o <= '0';
else
spdif_tx_o <= spdif_out;
end if;
end if;
end process TXSYNC;
-- State machine that generates sub-frames and blocks
FRST: process (up_clk)
begin
if rising_edge(up_clk) then
if resetn = '0' or conf_txen = '0' then
framest <= IDLE;
frame_cnt <= 0;
bit_cnt <= 0;
spdif_out <= '0';
inv_preamble <= '0';
toggle <= '0';
valid <= '1';
send_audio <= '0';
cha_samp_ack <= '0';
chb_samp_ack <= '0';
else
if spdif_clk_en = '1' then -- SPDIF clock is twice the bit rate
case framest is
when IDLE =>
bit_cnt <= 0;
frame_cnt <= 0;
inv_preamble <= '0';
toggle <= '0';
framest <= BLOCK_START;
when BLOCK_START => -- Start of channels status block/Ch. A
chb_samp_ack <= '0';
toggle <= not toggle; -- Each bit uses two clock enables,
if toggle = '1' then -- counted by the toggle bit.
if bit_cnt < 31 then
bit_cnt <= bit_cnt + 1;
else
bit_cnt <= 0;
if send_audio = '1' then
cha_samp_ack <= '1';
end if;
framest <= CHANNEL_B;
end if;
end if;
-- Block start uses preamble Z.
if bit_cnt < 4 then
if toggle = '0' then
spdif_out <= Z_PREAMBLE(2 * bit_cnt) xor inv_preamble;
else
spdif_out <= Z_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble;
end if;
par_cnt <= 0;
elsif bit_cnt > 3 and bit_cnt <= 31 then
spdif_out <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
if bit_cnt = 31 then
inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
end if;
if toggle = '0' then
if bit_cnt > 3 and bit_cnt < 31 and
par_vector(bit_cnt - 4) = '1' then
par_cnt <= par_cnt + 1;
end if;
end if;
end if;
when CHANNEL_A => -- Sub-frame: channel A.
chb_samp_ack <= '0';
toggle <= not toggle;
if toggle = '1' then
if bit_cnt < 31 then
bit_cnt <= bit_cnt + 1;
else
bit_cnt <= 0;
if spdif_out = '1' then
inv_preamble <= '1';
else
inv_preamble <= '0';
end if;
if send_audio = '1' then
cha_samp_ack <= '1';
end if;
framest <= CHANNEL_B;
end if;
end if;
-- Channel A uses preable X.
if bit_cnt < 4 then
if toggle = '0' then
spdif_out <= X_PREAMBLE(2 * bit_cnt) xor inv_preamble;
else
spdif_out <= X_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble;
end if;
par_cnt <= 0;
elsif bit_cnt > 3 and bit_cnt <= 31 then
spdif_out <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
if bit_cnt = 31 then
inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
end if;
if toggle = '0' then
if bit_cnt > 3 and bit_cnt < 31 and
par_vector(bit_cnt - 4) = '1' then
par_cnt <= par_cnt + 1;
end if;
end if;
end if;
when CHANNEL_B => -- Sub-frame: channel B.
cha_samp_ack <= '0';
toggle <= not toggle;
if toggle = '1' then
if bit_cnt < 31 then
bit_cnt <= bit_cnt + 1;
else
bit_cnt <= 0;
valid <= not conf_txdata;
if spdif_out = '1' then
inv_preamble <= '1';
else
inv_preamble <= '0';
end if;
send_audio <= conf_txdata; -- 1 if audio samples sohuld be sent
if send_audio = '1' then
chb_samp_ack <= '1';
end if;
if frame_cnt < 191 then -- One block is 192 frames
frame_cnt <= frame_cnt + 1;
framest <= CHANNEL_A;
else
frame_cnt <= 0;
framest <= BLOCK_START;
end if;
end if;
end if;
-- Channel B uses preable Y.
if bit_cnt < 4 then
if toggle = '0' then
spdif_out <= Y_PREAMBLE(2 * bit_cnt) xor inv_preamble;
else
spdif_out <= Y_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble;
end if;
par_cnt <= 0;
elsif bit_cnt > 3 and bit_cnt <= 31 then
spdif_out <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
if bit_cnt = 31 then
inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt,
par_cnt, active_user_data,
active_ch_status,
audio, toggle, spdif_out);
end if;
if toggle = '0' then
if bit_cnt > 3 and bit_cnt < 31 and
par_vector(bit_cnt - 4) = '1' then
par_cnt <= par_cnt + 1;
end if;
end if;
end if;
when others =>
framest <= IDLE;
end case;
end if;
end if;
end if;
end process FRST;
-- Audio data latching
DA32: if DATA_WIDTH = 32 generate
ALAT: process (up_clk)
begin
if rising_edge(up_clk) then
if send_audio = '0' then
audio(23 downto 0) <= (others => '0');
else
case to_integer(unsigned(conf_mode)) is
when 0 => -- 16 bit audio
audio(23 downto 8) <= sample_data(15 downto 0);
audio(7 downto 0) <= (others => '0');
when 1 => -- 17 bit audio
audio(23 downto 7) <= sample_data(16 downto 0);
audio(6 downto 0) <= (others => '0');
when 2 => -- 18 bit audio
audio(23 downto 6) <= sample_data(17 downto 0);
audio(5 downto 0) <= (others => '0');
when 3 => -- 19 bit audio
audio(23 downto 5) <= sample_data(18 downto 0);
audio(4 downto 0) <= (others => '0');
when 4 => -- 20 bit audio
audio(23 downto 4) <= sample_data(19 downto 0);
audio(3 downto 0) <= (others => '0');
when 5 => -- 21 bit audio
audio(23 downto 3) <= sample_data(20 downto 0);
audio(2 downto 0) <= (others => '0');
when 6 => -- 22 bit audio
audio(23 downto 2) <= sample_data(21 downto 0);
audio(1 downto 0) <= (others => '0');
when 7 => -- 23 bit audio
audio(23 downto 1) <= sample_data(22 downto 0);
audio(0) <= '0';
when 8 => -- 24 bit audio
audio(23 downto 0) <= sample_data(23 downto 0);
when others => -- unsupported modes
audio(23 downto 0) <= (others => '0');
end case;
end if;
end if;
end process ALAT;
end generate DA32;
DA16: if DATA_WIDTH = 16 generate
ALAT: process (up_clk)
begin
if rising_edge(up_clk) then
if send_audio = '0' then
audio(23 downto 0) <= (others => '0');
else
audio(23 downto 8) <= sample_data(15 downto 0);
audio(7 downto 0) <= (others => '0');
end if;
end if;
end process ALAT;
end generate DA16;
-- Parity vector. These bits are counted to generate even parity
par_vector(23 downto 0) <= audio(23 downto 0);
par_vector(24) <= valid;
par_vector(25) <= active_user_data(frame_cnt);
par_vector(26) <= active_ch_status(frame_cnt);
-- Channel status and user datat to be used if buffers are disabled.
-- User data is then all zero, while channel status bits are taken from
-- register TxChStat.
def_user_data(191 downto 0) <= (others => '0');
def_ch_status(0) <= '0'; -- consumer mode
def_ch_status(1) <= chstat_audio; -- audio bit
def_ch_status(2) <= chstat_copy; -- copy right
def_ch_status(5 downto 3) <= "000" when chstat_preem = '0'
else "001"; -- pre-emphasis
def_ch_status(7 downto 6) <= "00";
def_ch_status(14 downto 8) <= (others => '0');
def_ch_status(15) <= chstat_gstat; -- generation status
def_ch_status(23 downto 16) <= (others => '0');
def_ch_status(27 downto 24) <= "0000" when chstat_freq = "00" else
"0010" when chstat_freq = "01" else
"0011" when chstat_freq = "10" else
"0001";
def_ch_status(191 downto 28) <= (others => '0'); --191 28
-- Generate channel status vector based on configuration register setting.
active_ch_status <= def_ch_status;
-- Generate user data vector based on configuration register setting.
active_user_data <= def_user_data;
end rtl;

View File

@ -0,0 +1,88 @@
----------------------------------------------------------------------
---- ----
---- WISHBONE SPDIF IP Core ----
---- ----
---- This file is part of the SPDIF project ----
---- http://www.opencores.org/cores/spdif_interface/ ----
---- ----
---- Description ----
---- SPDIF transmitter component package. ----
---- ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Geir Drange, gedra@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2004 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source 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. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/07/14 17:58:49 gedra
-- Added new components.
--
-- Revision 1.1 2004/07/13 18:30:25 gedra
-- Transmitter component declarations.
--
--
--
library ieee;
use ieee.std_logic_1164.all;
package tx_package is
component tx_encoder
generic
(
DATA_WIDTH: integer range 16 to 32 := 32
);
port
(
up_clk: in std_logic; -- clock
data_clk : in std_logic; -- data clock
resetn : in std_logic; -- resetn
conf_mode: in std_logic_vector(3 downto 0); -- sample format
conf_ratio: in std_logic_vector(7 downto 0); -- clock divider
conf_txdata: in std_logic; -- sample data enable
conf_txen: in std_logic; -- spdif signal enable
chstat_freq: in std_logic_vector(1 downto 0); -- sample freq.
chstat_gstat: in std_logic; -- generation status
chstat_preem: in std_logic; -- preemphasis status
chstat_copy: in std_logic; -- copyright bit
chstat_audio: in std_logic; -- data format
sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data
sample_data_ack : out std_logic; -- sample buffer read
channel: out std_logic;
spdif_tx_o: out std_logic
);
end component;
end tx_package;

View File

@ -0,0 +1,330 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_axis_dma_rx (
// dma interface
dma_clk,
dma_rst,
dma_valid,
dma_last,
dma_data,
dma_ready,
dma_ovf,
dma_unf,
dma_status,
dma_bw,
// data interface
adc_clk,
adc_rst,
adc_valid,
adc_data,
// processor interface
dma_start,
dma_stream,
dma_count);
// parameters
parameter DATA_WIDTH = 64;
localparam DW = DATA_WIDTH - 1;
localparam BUF_THRESHOLD_LO = 6'd3;
localparam BUF_THRESHOLD_HI = 6'd60;
localparam DATA_WIDTH_IN_BYTES = DATA_WIDTH/8;
// dma interface
input dma_clk;
input dma_rst;
output dma_valid;
output dma_last;
output [DW:0] dma_data;
input dma_ready;
output dma_ovf;
output dma_unf;
output dma_status;
output [31:0] dma_bw;
// data interface
input adc_clk;
input adc_rst;
input adc_valid;
input [DW:0] adc_data;
// processor interface
input dma_start;
input dma_stream;
input [31:0] dma_count;
// internal registers
reg dma_valid_int = 'd0;
reg dma_last_int = 'd0;
reg [DW:0] dma_data_int = 'd0;
reg dma_capture_enable = 'd0;
reg [31:0] dma_capture_count = 'd0;
reg dma_rd = 'd0;
reg [ 5:0] dma_raddr = 'd0;
reg dma_release_toggle_m1 = 'd0;
reg dma_release_toggle_m2 = 'd0;
reg dma_release_toggle_m3 = 'd0;
reg [ 5:0] dma_release_waddr = 'd0;
reg [ 5:0] dma_waddr_m1 = 'd0;
reg [ 5:0] dma_waddr_m2 = 'd0;
reg [ 5:0] dma_waddr = 'd0;
reg [ 5:0] dma_addr_diff = 'd0;
reg dma_almost_full = 'd0;
reg dma_almost_empty = 'd0;
reg dma_ovf = 'd0;
reg dma_unf = 'd0;
reg dma_resync = 'd0;
reg adc_wr = 'd0;
reg [ 5:0] adc_waddr = 'd0;
reg [ 5:0] adc_waddr_g = 'd0;
reg [ 3:0] adc_release_count = 'd0;
reg [DW:0] adc_wdata = 'd0;
reg adc_release_toggle = 'd0;
reg [ 5:0] adc_release_waddr = 'd0;
reg adc_resync_m1 = 'd0;
reg adc_resync_m2 = 'd0;
reg adc_resync = 'd0;
// internal signals
wire dma_rd_valid_s;
wire dma_last_s;
wire dma_ready_s;
wire dma_rd_s;
wire dma_release_s;
wire [ 6:0] dma_addr_diff_s;
wire dma_ovf_s;
wire dma_unf_s;
wire [DW:0] dma_rdata_s;
// binary to grey conversion
function [5:0] b2g;
input [5:0] b;
reg [5:0] g;
begin
g[5] = b[5];
g[4] = b[5] ^ b[4];
g[3] = b[4] ^ b[3];
g[2] = b[3] ^ b[2];
g[1] = b[2] ^ b[1];
g[0] = b[1] ^ b[0];
b2g = g;
end
endfunction
// grey to binary conversion
function [5:0] g2b;
input [5:0] g;
reg [5:0] b;
begin
b[5] = g[5];
b[4] = b[5] ^ g[4];
b[3] = b[4] ^ g[3];
b[2] = b[3] ^ g[2];
b[1] = b[2] ^ g[1];
b[0] = b[1] ^ g[0];
g2b = b;
end
endfunction
// dma read- user interface
assign dma_bw = DATA_WIDTH_IN_BYTES;
assign dma_status = dma_capture_enable;
always @(posedge dma_clk) begin
dma_valid_int <= dma_rd_valid_s;
dma_last_int <= dma_last_s;
dma_data_int <= dma_rdata_s;
end
// dma read- capture control signals
assign dma_rd_valid_s = dma_capture_enable & dma_rd;
assign dma_last_s = (dma_capture_count == dma_count) ? dma_rd_valid_s : 1'b0;
always @(posedge dma_clk) begin
if ((dma_stream == 1'b0) && (dma_last_s == 1'b1)) begin
dma_capture_enable <= 1'b0;
end else if (dma_start == 1'b1) begin
dma_capture_enable <= 1'b1;
end
if ((dma_capture_enable == 1'b0) || (dma_last_s == 1'b1)) begin
dma_capture_count <= dma_bw;
end else if (dma_rd == 1'b1) begin
dma_capture_count <= dma_capture_count + dma_bw;
end
end
// dma read- read data always and pass it to the external memory
assign dma_ready_s = (~dma_capture_enable) | dma_ready;
assign dma_rd_s = (dma_release_waddr == dma_raddr) ? 1'b0 : dma_ready_s;
always @(posedge dma_clk) begin
dma_rd <= dma_rd_s;
if ((dma_resync == 1'b1) || (dma_rst == 1'b1)) begin
dma_raddr <= 6'd0;
end else if (dma_rd_s == 1'b1) begin
dma_raddr <= dma_raddr + 1'b1;
end
end
// dma read- get bursts of adc data from the other side
assign dma_release_s = dma_release_toggle_m3 ^ dma_release_toggle_m2;
always @(posedge dma_clk) begin
if (dma_rst == 1'b1) begin
dma_release_toggle_m1 <= 'd0;
dma_release_toggle_m2 <= 'd0;
dma_release_toggle_m3 <= 'd0;
end else begin
dma_release_toggle_m1 <= adc_release_toggle;
dma_release_toggle_m2 <= dma_release_toggle_m1;
dma_release_toggle_m3 <= dma_release_toggle_m2;
end
if (dma_resync == 1'b1) begin
dma_release_waddr <= 6'd0;
end else if (dma_release_s == 1'b1) begin
dma_release_waddr <= adc_release_waddr;
end
end
// dma read- get free running write address for ovf/unf checking
assign dma_addr_diff_s = {1'b1, dma_waddr} - dma_raddr;
assign dma_ovf_s = (dma_addr_diff < BUF_THRESHOLD_LO) ? dma_almost_full : 1'b0;
assign dma_unf_s = (dma_addr_diff > BUF_THRESHOLD_HI) ? dma_almost_empty : 1'b0;
always @(posedge dma_clk) begin
if (dma_rst == 1'b1) begin
dma_waddr_m1 <= 'd0;
dma_waddr_m2 <= 'd0;
end else begin
dma_waddr_m1 <= adc_waddr_g;
dma_waddr_m2 <= dma_waddr_m1;
end
dma_waddr <= g2b(dma_waddr_m2);
dma_addr_diff <= dma_addr_diff_s[5:0];
if (dma_addr_diff > BUF_THRESHOLD_HI) begin
dma_almost_full <= 1'b1;
end else begin
dma_almost_full <= 1'b0;
end
if (dma_addr_diff < BUF_THRESHOLD_LO) begin
dma_almost_empty <= 1'b1;
end else begin
dma_almost_empty <= 1'b0;
end
dma_ovf <= dma_ovf_s;
dma_unf <= dma_unf_s;
dma_resync <= dma_ovf | dma_unf;
end
// adc write- used here to simply transfer data to the dma side
// address is released with a free running counter
always @(posedge adc_clk) begin
adc_wr <= adc_valid;
if ((adc_resync == 1'b1) || (adc_rst == 1'b1)) begin
adc_waddr <= 6'd0;
end else if (adc_wr == 1'b1) begin
adc_waddr <= adc_waddr + 1'b1;
end
adc_waddr_g <= b2g(adc_waddr);
adc_wdata <= adc_data;
adc_release_count <= adc_release_count + 1'b1;
if (adc_release_count == 4'hf) begin
adc_release_toggle <= ~adc_release_toggle;
adc_release_waddr <= adc_waddr;
end
if (adc_rst == 1'b1) begin
adc_resync_m1 <= 'd0;
adc_resync_m2 <= 'd0;
end else begin
adc_resync_m1 <= dma_resync;
adc_resync_m2 <= adc_resync_m1;
end
adc_resync <= adc_resync_m2;
end
// interface handler for ready
ad_axis_inf_rx #(.DATA_WIDTH(DATA_WIDTH)) i_axis_inf (
.clk (dma_clk),
.rst (dma_rst),
.valid (dma_valid_int),
.last (dma_last_int),
.data (dma_data_int),
.inf_valid (dma_valid),
.inf_last (dma_last),
.inf_data (dma_data),
.inf_ready (dma_ready));
// buffer (mainly for clock domain transfer)
ad_mem #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(6)) i_mem (
.clka (adc_clk),
.wea (adc_wr),
.addra (adc_waddr),
.dina (adc_wdata),
.clkb (dma_clk),
.addrb (dma_raddr),
.doutb (dma_rdata_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,281 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// dac vdma read
module ad_axis_dma_tx (
// vdma interface
dma_clk,
dma_rst,
dma_fs,
dma_valid,
dma_data,
dma_ready,
dma_ovf,
dma_unf,
// dac interface
dac_clk,
dac_rst,
dac_rd,
dac_valid,
dac_data,
// processor interface
dma_frmcnt);
// parameters
parameter DATA_WIDTH = 64;
localparam DW = DATA_WIDTH - 1;
localparam BUF_THRESHOLD_LO = 6'd3;
localparam BUF_THRESHOLD_HI = 6'd60;
localparam RDY_THRESHOLD_LO = 6'd40;
localparam RDY_THRESHOLD_HI = 6'd50;
// vdma interface
input dma_clk;
input dma_rst;
output dma_fs;
input dma_valid;
input [DW:0] dma_data;
output dma_ready;
output dma_ovf;
output dma_unf;
// dac interface
input dac_clk;
input dac_rst;
input dac_rd;
output dac_valid;
output [DW:0] dac_data;
// processor interface
input [31:0] dma_frmcnt;
// internal registers
reg dac_start_m1 = 'd0;
reg dac_start = 'd0;
reg dac_resync_m1 = 'd0;
reg dac_resync = 'd0;
reg [ 5:0] dac_raddr = 'd0;
reg [ 5:0] dac_raddr_g = 'd0;
reg dac_rd_d = 'd0;
reg dac_rd_2d = 'd0;
reg dac_valid = 'd0;
reg [DW:0] dac_data = 'd0;
reg [31:0] dma_clkcnt = 'd0;
reg dma_fs = 'd0;
reg [ 5:0] dma_raddr_g_m1 = 'd0;
reg [ 5:0] dma_raddr_g_m2 = 'd0;
reg [ 5:0] dma_raddr = 'd0;
reg [ 5:0] dma_addr_diff = 'd0;
reg dma_ready = 'd0;
reg dma_almost_full = 'd0;
reg dma_almost_empty = 'd0;
reg dma_ovf = 'd0;
reg dma_unf = 'd0;
reg dma_resync = 'd0;
reg dma_start = 'd0;
reg dma_wr = 'd0;
reg [ 5:0] dma_waddr = 'd0;
reg [DW:0] dma_wdata = 'd0;
// internal signals
wire dma_wr_s;
wire [ 6:0] dma_addr_diff_s;
wire dma_ovf_s;
wire dma_unf_s;
wire [DW:0] dac_rdata_s;
// binary to grey coversion
function [7:0] b2g;
input [7:0] b;
reg [7:0] g;
begin
g[7] = b[7];
g[6] = b[7] ^ b[6];
g[5] = b[6] ^ b[5];
g[4] = b[5] ^ b[4];
g[3] = b[4] ^ b[3];
g[2] = b[3] ^ b[2];
g[1] = b[2] ^ b[1];
g[0] = b[1] ^ b[0];
b2g = g;
end
endfunction
// grey to binary conversion
function [7:0] g2b;
input [7:0] g;
reg [7:0] b;
begin
b[7] = g[7];
b[6] = b[7] ^ g[6];
b[5] = b[6] ^ g[5];
b[4] = b[5] ^ g[4];
b[3] = b[4] ^ g[3];
b[2] = b[3] ^ g[2];
b[1] = b[2] ^ g[1];
b[0] = b[1] ^ g[0];
g2b = b;
end
endfunction
// dac read interface
always @(posedge dac_clk) begin
if (dac_rst == 1'b1) begin
dac_start_m1 <= 'd0;
dac_start <= 'd0;
dac_resync_m1 <= 'd0;
dac_resync <= 'd0;
end else begin
dac_start_m1 <= dma_start;
dac_start <= dac_start_m1;
dac_resync_m1 <= dma_resync;
dac_resync <= dac_resync_m1;
end
if ((dac_start == 1'b0) || (dac_resync == 1'b1) || (dac_rst == 1'b1)) begin
dac_raddr <= 6'd0;
end else if (dac_rd == 1'b1) begin
dac_raddr <= dac_raddr + 1'b1;
end
dac_raddr_g <= b2g(dac_raddr);
dac_rd_d <= dac_rd;
dac_rd_2d <= dac_rd_d;
dac_valid <= dac_rd_2d;
dac_data <= dac_rdata_s;
end
// generate fsync
always @(posedge dma_clk) begin
if ((dma_resync == 1'b1) || (dma_rst == 1'b1) || (dma_clkcnt >= dma_frmcnt)) begin
dma_clkcnt <= 16'd0;
end else begin
dma_clkcnt <= dma_clkcnt + 1'b1;
end
if (dma_clkcnt == 32'd1) begin
dma_fs <= 1'b1;
end else begin
dma_fs <= 1'b0;
end
end
// overflow or underflow status
assign dma_addr_diff_s = {1'b1, dma_waddr} - dma_raddr;
assign dma_ovf_s = (dma_addr_diff < BUF_THRESHOLD_LO) ? dma_almost_full : 1'b0;
assign dma_unf_s = (dma_addr_diff > BUF_THRESHOLD_HI) ? dma_almost_empty : 1'b0;
always @(posedge dma_clk) begin
if (dma_rst == 1'b1) begin
dma_raddr_g_m1 <= 'd0;
dma_raddr_g_m2 <= 'd0;
end else begin
dma_raddr_g_m1 <= dac_raddr_g;
dma_raddr_g_m2 <= dma_raddr_g_m1;
end
dma_raddr <= g2b(dma_raddr_g_m2);
dma_addr_diff <= dma_addr_diff_s[5:0];
if (dma_addr_diff >= RDY_THRESHOLD_HI) begin
dma_ready <= 1'b0;
end else if (dma_addr_diff <= RDY_THRESHOLD_LO) begin
dma_ready <= 1'b1;
end
if (dma_addr_diff > BUF_THRESHOLD_HI) begin
dma_almost_full <= 1'b1;
end else begin
dma_almost_full <= 1'b0;
end
if (dma_addr_diff < BUF_THRESHOLD_LO) begin
dma_almost_empty <= 1'b1;
end else begin
dma_almost_empty <= 1'b0;
end
dma_ovf <= dma_ovf_s;
dma_unf <= dma_unf_s;
dma_resync <= dma_ovf | dma_unf;
end
// vdma write
assign dma_wr_s = dma_valid & dma_ready;
always @(posedge dma_clk) begin
if (dma_rst == 1'b1) begin
dma_start <= 1'b0;
end else if (dma_wr_s == 1'b1) begin
dma_start <= 1'b1;
end
dma_wr <= dma_wr_s;
if ((dma_resync == 1'b1) || (dma_rst == 1'b1)) begin
dma_waddr <= 6'd0;
end else if (dma_wr == 1'b1) begin
dma_waddr <= dma_waddr + 1'b1;
end
dma_wdata <= dma_data;
end
// memory
ad_mem #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(6)) i_mem (
.clka (dma_clk),
.wea (dma_wr),
.addra (dma_waddr),
.dina (dma_wdata),
.clkb (dac_clk),
.addrb (dac_raddr),
.doutb (dac_rdata_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,206 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// Xilinx ip cores are not fifo friendly and require a hard stop on the interface
// valid & data can not change, if ready is deasserted (if they do you will have to
// roll it back).
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_axis_inf_rx (
// adi interface
clk,
rst,
valid,
last,
data,
// xilinx interface
inf_valid,
inf_last,
inf_data,
inf_ready);
// parameter for data width
parameter DATA_WIDTH = 16;
localparam DW = DATA_WIDTH - 1;
// adi interface
input clk;
input rst;
input valid;
input last;
input [DW:0] data;
// xil interface
output inf_valid;
output inf_last;
output [DW:0] inf_data;
input inf_ready;
// internal registers
reg [ 2:0] wcnt = 'd0;
reg wlast_0 = 'd0;
reg [DW:0] wdata_0 = 'd0;
reg wlast_1 = 'd0;
reg [DW:0] wdata_1 = 'd0;
reg wlast_2 = 'd0;
reg [DW:0] wdata_2 = 'd0;
reg wlast_3 = 'd0;
reg [DW:0] wdata_3 = 'd0;
reg wlast_4 = 'd0;
reg [DW:0] wdata_4 = 'd0;
reg wlast_5 = 'd0;
reg [DW:0] wdata_5 = 'd0;
reg wlast_6 = 'd0;
reg [DW:0] wdata_6 = 'd0;
reg wlast_7 = 'd0;
reg [DW:0] wdata_7 = 'd0;
reg [ 2:0] rcnt = 'd0;
reg inf_valid = 'd0;
reg inf_last = 'd0;
reg [DW:0] inf_data = 'd0;
// write interface
always @(posedge clk) begin
if (rst == 1'b1) begin
wcnt <= 'd0;
end else if (valid == 1'b1) begin
wcnt <= wcnt + 1'b1;
end
if ((wcnt == 3'd0) && (valid == 1'b1)) begin
wlast_0 <= last;
wdata_0 <= data;
end
if ((wcnt == 3'd1) && (valid == 1'b1)) begin
wlast_1 <= last;
wdata_1 <= data;
end
if ((wcnt == 3'd2) && (valid == 1'b1)) begin
wlast_2 <= last;
wdata_2 <= data;
end
if ((wcnt == 3'd3) && (valid == 1'b1)) begin
wlast_3 <= last;
wdata_3 <= data;
end
if ((wcnt == 3'd4) && (valid == 1'b1)) begin
wlast_4 <= last;
wdata_4 <= data;
end
if ((wcnt == 3'd5) && (valid == 1'b1)) begin
wlast_5 <= last;
wdata_5 <= data;
end
if ((wcnt == 3'd6) && (valid == 1'b1)) begin
wlast_6 <= last;
wdata_6 <= data;
end
if ((wcnt == 3'd7) && (valid == 1'b1)) begin
wlast_7 <= last;
wdata_7 <= data;
end
end
// read interface
always @(posedge clk) begin
if (rst == 1'b1) begin
rcnt <= 'd0;
inf_valid <= 'd0;
inf_last <= 'b0;
inf_data <= 'd0;
end else if ((inf_ready == 1'b1) || (inf_valid == 1'b0)) begin
if (rcnt == wcnt) begin
rcnt <= rcnt;
inf_valid <= 1'd0;
inf_last <= 1'b0;
inf_data <= 'd0;
end else begin
rcnt <= rcnt + 1'b1;
inf_valid <= 1'b1;
case (rcnt)
3'd0: begin
inf_last <= wlast_0;
inf_data <= wdata_0;
end
3'd1: begin
inf_last <= wlast_1;
inf_data <= wdata_1;
end
3'd2: begin
inf_last <= wlast_2;
inf_data <= wdata_2;
end
3'd3: begin
inf_last <= wlast_3;
inf_data <= wdata_3;
end
3'd4: begin
inf_last <= wlast_4;
inf_data <= wdata_4;
end
3'd5: begin
inf_last <= wlast_5;
inf_data <= wdata_5;
end
3'd6: begin
inf_last <= wlast_6;
inf_data <= wdata_6;
end
default: begin
inf_last <= wlast_7;
inf_data <= wdata_7;
end
endcase
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

136
library/common/ad_csc_1.v Normal file
View File

@ -0,0 +1,136 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// csc = c1*d[23:16] + c2*d[15:8] + c3*d[7:0] + c4;
module ad_csc_1 (
// data
clk,
sync,
data,
// constants
C1,
C2,
C3,
C4,
// sync is delay matched
csc_sync_1,
csc_data_1);
// parameters
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// data
input clk;
input [DW:0] sync;
input [23:0] data;
// constants
input [16:0] C1;
input [16:0] C2;
input [16:0] C3;
input [24:0] C4;
// sync is delay matched
output [DW:0] csc_sync_1;
output [ 7:0] csc_data_1;
// internal wires
wire [24:0] data_1_m_s;
wire [24:0] data_2_m_s;
wire [24:0] data_3_m_s;
wire [DW:0] sync_3_m_s;
// c1*R
ad_csc_1_mul #(.DELAY_DATA_WIDTH(1)) i_mul_c1 (
.clk (clk),
.data_a (C1),
.data_b (data[23:16]),
.data_p (data_1_m_s),
.ddata_in (1'd0),
.ddata_out ());
// c2*G
ad_csc_1_mul #(.DELAY_DATA_WIDTH(1)) i_mul_c2 (
.clk (clk),
.data_a (C2),
.data_b (data[15:8]),
.data_p (data_2_m_s),
.ddata_in (1'd0),
.ddata_out ());
// c3*B
ad_csc_1_mul #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_mul_c3 (
.clk (clk),
.data_a (C3),
.data_b (data[7:0]),
.data_p (data_3_m_s),
.ddata_in (sync),
.ddata_out (sync_3_m_s));
// sum + c4
ad_csc_1_add #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_add_c4 (
.clk (clk),
.data_1 (data_1_m_s),
.data_2 (data_2_m_s),
.data_3 (data_3_m_s),
.data_4 (C4),
.data_p (csc_data_1),
.ddata_in (sync_3_m_s),
.ddata_out (csc_sync_1));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,168 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Color Space Conversion, adder. This is a simple adder, but had to be
// pipe-lined for faster clock rates. The delay input is delay-matched to
// the sum pipe-line stages
`timescale 1ps/1ps
module ad_csc_1_add (
// all signed
clk,
data_1,
data_2,
data_3,
data_4,
data_p,
// delay match
ddata_in,
ddata_out);
// parameters
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// all signed
input clk;
input [24:0] data_1;
input [24:0] data_2;
input [24:0] data_3;
input [24:0] data_4;
output [ 7:0] data_p;
// delay match
input [DW:0] ddata_in;
output [DW:0] ddata_out;
// internal registers
reg [DW:0] p1_ddata = 'd0;
reg [24:0] p1_data_1 = 'd0;
reg [24:0] p1_data_2 = 'd0;
reg [24:0] p1_data_3 = 'd0;
reg [24:0] p1_data_4 = 'd0;
reg [DW:0] p2_ddata = 'd0;
reg [24:0] p2_data_0 = 'd0;
reg [24:0] p2_data_1 = 'd0;
reg [DW:0] p3_ddata = 'd0;
reg [24:0] p3_data = 'd0;
reg [DW:0] ddata_out = 'd0;
reg [ 7:0] data_p = 'd0;
// internal signals
wire [24:0] p1_data_1_p_s;
wire [24:0] p1_data_1_n_s;
wire [24:0] p1_data_1_s;
wire [24:0] p1_data_2_p_s;
wire [24:0] p1_data_2_n_s;
wire [24:0] p1_data_2_s;
wire [24:0] p1_data_3_p_s;
wire [24:0] p1_data_3_n_s;
wire [24:0] p1_data_3_s;
wire [24:0] p1_data_4_p_s;
wire [24:0] p1_data_4_n_s;
wire [24:0] p1_data_4_s;
// pipe line stage 1, get the two's complement versions
assign p1_data_1_p_s = {1'b0, data_1[23:0]};
assign p1_data_1_n_s = ~p1_data_1_p_s + 1'b1;
assign p1_data_1_s = (data_1[24] == 1'b1) ? p1_data_1_n_s : p1_data_1_p_s;
assign p1_data_2_p_s = {1'b0, data_2[23:0]};
assign p1_data_2_n_s = ~p1_data_2_p_s + 1'b1;
assign p1_data_2_s = (data_2[24] == 1'b1) ? p1_data_2_n_s : p1_data_2_p_s;
assign p1_data_3_p_s = {1'b0, data_3[23:0]};
assign p1_data_3_n_s = ~p1_data_3_p_s + 1'b1;
assign p1_data_3_s = (data_3[24] == 1'b1) ? p1_data_3_n_s : p1_data_3_p_s;
assign p1_data_4_p_s = {1'b0, data_4[23:0]};
assign p1_data_4_n_s = ~p1_data_4_p_s + 1'b1;
assign p1_data_4_s = (data_4[24] == 1'b1) ? p1_data_4_n_s : p1_data_4_p_s;
always @(posedge clk) begin
p1_ddata <= ddata_in;
p1_data_1 <= p1_data_1_s;
p1_data_2 <= p1_data_2_s;
p1_data_3 <= p1_data_3_s;
p1_data_4 <= p1_data_4_s;
end
// pipe line stage 2, get the sum (intermediate, 4->2)
always @(posedge clk) begin
p2_ddata <= p1_ddata;
p2_data_0 <= p1_data_1 + p1_data_2;
p2_data_1 <= p1_data_3 + p1_data_4;
end
// pipe line stage 3, get the sum (final, 2->1)
always @(posedge clk) begin
p3_ddata <= p2_ddata;
p3_data <= p2_data_0 + p2_data_1;
end
// output registers, output is unsigned (0 if sum is < 0) and saturated.
// the inputs are expected to be 1.4.20 format (output is 8bits).
always @(posedge clk) begin
ddata_out <= p3_ddata;
if (p3_data[24] == 1'b1) begin
data_p <= 8'h00;
end else if (p3_data[23:20] == 'd0) begin
data_p <= p3_data[19:12];
end else begin
data_p <= 8'hff;
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,184 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Color Space Conversion, multiplier. This is a simple partial product adder
// that generates the product of the two inputs.
`timescale 1ps/1ps
module ad_csc_1_mul (
// data_a is signed
clk,
data_a,
data_b,
data_p,
// delay match
ddata_in,
ddata_out);
// parameters
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// data_a is signed
input clk;
input [16:0] data_a;
input [ 7:0] data_b;
output [24:0] data_p;
// delay match
input [DW:0] ddata_in;
output [DW:0] ddata_out;
// internal registers
reg p1_sign = 'd0;
reg [DW:0] p1_ddata = 'd0;
reg [23:0] p1_data_p_0 = 'd0;
reg [23:0] p1_data_p_1 = 'd0;
reg [23:0] p1_data_p_2 = 'd0;
reg [23:0] p1_data_p_3 = 'd0;
reg [23:0] p1_data_p_4 = 'd0;
reg p2_sign = 'd0;
reg [DW:0] p2_ddata = 'd0;
reg [23:0] p2_data_p_0 = 'd0;
reg [23:0] p2_data_p_1 = 'd0;
reg p3_sign = 'd0;
reg [DW:0] p3_ddata = 'd0;
reg [23:0] p3_data_p_0 = 'd0;
reg [DW:0] ddata_out = 'd0;
reg [24:0] data_p = 'd0;
// internal wires
wire [16:0] p1_data_a_1p_17_s;
wire [16:0] p1_data_a_1n_17_s;
wire [23:0] p1_data_a_1p_s;
wire [23:0] p1_data_a_1n_s;
wire [23:0] p1_data_a_2p_s;
wire [23:0] p1_data_a_2n_s;
// pipe line stage 1, get the two's complement versions
assign p1_data_a_1p_17_s = {1'b0, data_a[15:0]};
assign p1_data_a_1n_17_s = ~p1_data_a_1p_17_s + 1'b1;
assign p1_data_a_1p_s = {{7{p1_data_a_1p_17_s[16]}}, p1_data_a_1p_17_s};
assign p1_data_a_1n_s = {{7{p1_data_a_1n_17_s[16]}}, p1_data_a_1n_17_s};
assign p1_data_a_2p_s = {{6{p1_data_a_1p_17_s[16]}}, p1_data_a_1p_17_s, 1'b0};
assign p1_data_a_2n_s = {{6{p1_data_a_1n_17_s[16]}}, p1_data_a_1n_17_s, 1'b0};
// pipe line stage 1, get the partial products
always @(posedge clk) begin
p1_sign <= data_a[16];
p1_ddata <= ddata_in;
case (data_b[1:0])
2'b11: p1_data_p_0 <= p1_data_a_1n_s;
2'b10: p1_data_p_0 <= p1_data_a_2n_s;
2'b01: p1_data_p_0 <= p1_data_a_1p_s;
default: p1_data_p_0 <= 24'd0;
endcase
case (data_b[3:1])
3'b011: p1_data_p_1 <= {p1_data_a_2p_s[21:0], 2'd0};
3'b100: p1_data_p_1 <= {p1_data_a_2n_s[21:0], 2'd0};
3'b001: p1_data_p_1 <= {p1_data_a_1p_s[21:0], 2'd0};
3'b010: p1_data_p_1 <= {p1_data_a_1p_s[21:0], 2'd0};
3'b101: p1_data_p_1 <= {p1_data_a_1n_s[21:0], 2'd0};
3'b110: p1_data_p_1 <= {p1_data_a_1n_s[21:0], 2'd0};
default: p1_data_p_1 <= 24'd0;
endcase
case (data_b[5:3])
3'b011: p1_data_p_2 <= {p1_data_a_2p_s[19:0], 4'd0};
3'b100: p1_data_p_2 <= {p1_data_a_2n_s[19:0], 4'd0};
3'b001: p1_data_p_2 <= {p1_data_a_1p_s[19:0], 4'd0};
3'b010: p1_data_p_2 <= {p1_data_a_1p_s[19:0], 4'd0};
3'b101: p1_data_p_2 <= {p1_data_a_1n_s[19:0], 4'd0};
3'b110: p1_data_p_2 <= {p1_data_a_1n_s[19:0], 4'd0};
default: p1_data_p_2 <= 24'd0;
endcase
case (data_b[7:5])
3'b011: p1_data_p_3 <= {p1_data_a_2p_s[17:0], 6'd0};
3'b100: p1_data_p_3 <= {p1_data_a_2n_s[17:0], 6'd0};
3'b001: p1_data_p_3 <= {p1_data_a_1p_s[17:0], 6'd0};
3'b010: p1_data_p_3 <= {p1_data_a_1p_s[17:0], 6'd0};
3'b101: p1_data_p_3 <= {p1_data_a_1n_s[17:0], 6'd0};
3'b110: p1_data_p_3 <= {p1_data_a_1n_s[17:0], 6'd0};
default: p1_data_p_3 <= 24'd0;
endcase
case (data_b[7])
1'b1: p1_data_p_4 <= {p1_data_a_1p_s[15:0], 8'd0};
default: p1_data_p_4 <= 24'd0;
endcase
end
// pipe line stage 2, get the sum (intermediate 5 -> 2)
always @(posedge clk) begin
p2_sign <= p1_sign;
p2_ddata <= p1_ddata;
p2_data_p_0 <= p1_data_p_0 + p1_data_p_1 + p1_data_p_4;
p2_data_p_1 <= p1_data_p_2 + p1_data_p_3;
end
// pipe line stage 2, get the sum (final 2 -> 1)
always @(posedge clk) begin
p3_sign <= p2_sign;
p3_ddata <= p2_ddata;
p3_data_p_0 <= p2_data_p_0 + p2_data_p_1;
end
// output registers (truncation occurs after addition, see ad_csc_1_add.v)
always @(posedge clk) begin
ddata_out <= p3_ddata;
data_p <= {p3_sign, p3_data_p_0};
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,117 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Transmit HDMI, RGB to CrYCb conversion
// The multiplication coefficients are in 1.4.12 format
// The addition coefficients are in 1.12.12 format
// Cr = (+112.439/256)*R + (-094.154/256)*G + (-018.285/256)*B + 128;
// Y = (+065.738/256)*R + (+129.057/256)*G + (+025.064/256)*B + 16;
// Cb = (-037.945/256)*R + (-074.494/256)*G + (+112.439/256)*B + 128;
module ad_csc_RGB2CrYCb (
// R-G-B inputs
clk,
RGB_sync,
RGB_data,
// Cr-Y-Cb outputs
CrYCb_sync,
CrYCb_data);
// parameters
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// R-G-B inputs
input clk;
input [DW:0] RGB_sync;
input [23:0] RGB_data;
// Cr-Y-Cb outputs
output [DW:0] CrYCb_sync;
output [23:0] CrYCb_data;
// Cr (red-diff)
ad_csc_1 #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_csc_1_Cr (
.clk (clk),
.sync (RGB_sync),
.data (RGB_data),
.C1 (17'h00707),
.C2 (17'h105e2),
.C3 (17'h10124),
.C4 (25'h0080000),
.csc_sync_1 (CrYCb_sync),
.csc_data_1 (CrYCb_data[23:16]));
// Y (luma)
ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_Y (
.clk (clk),
.sync (1'd0),
.data (RGB_data),
.C1 (17'h0041b),
.C2 (17'h00810),
.C3 (17'h00191),
.C4 (25'h0010000),
.csc_sync_1 (),
.csc_data_1 (CrYCb_data[15:8]));
// Cb (blue-diff)
ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_Cb (
.clk (clk),
.sync (1'd0),
.data (RGB_data),
.C1 (17'h1025f),
.C2 (17'h104a7),
.C3 (17'h00707),
.C4 (25'h0080000),
.csc_sync_1 (),
.csc_data_1 (CrYCb_data[7:0]));
endmodule
// ***************************************************************************
// ***************************************************************************

108
library/common/ad_datafmt.v Normal file
View File

@ -0,0 +1,108 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// data format (offset binary or 2's complement only)
`timescale 1ps/1ps
module ad_datafmt (
// data path
clk,
valid,
data,
valid_out,
data_out,
// control signals
dfmt_enable,
dfmt_type,
dfmt_se);
// delayed data bus width
parameter DATA_WIDTH = 16;
localparam DW = DATA_WIDTH - 1;
// data path
input clk;
input valid;
input [DW:0] data;
output valid_out;
output [15:0] data_out;
// control signals
input dfmt_enable;
input dfmt_type;
input dfmt_se;
// internal registers
reg valid_out = 'd0;
reg [15:0] data_out = 'd0;
// internal signals
wire type_s;
wire signext_s;
wire [DW:0] data_s;
wire [23:0] sign_s;
wire [23:0] data_out_s;
// if offset-binary convert to 2's complement first
assign type_s = dfmt_enable & dfmt_type;
assign signext_s = dfmt_enable & dfmt_se;
assign data_s = (type_s == 1'b1) ? {~data[DW], data[(DW-1):0]} : data;
assign sign_s = (signext_s == 1'b1) ? {{24{data_s[DW]}}} : 24'd0;
assign data_out_s = {sign_s[23:(DW+1)], data_s};
always @(posedge clk) begin
valid_out <= valid;
data_out <= data_out_s[15:0];
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,113 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// dc filter- y(n) = c*x(n) + (1-c)*y(n-1)
`timescale 1ps/1ps
module ad_dcfilter (
// data interface
clk,
valid,
data,
valid_out,
data_out,
// control interface
dcfilt_enb,
dcfilt_coeff,
dcfilt_offset);
// data interface
input clk;
input valid;
input [15:0] data;
output valid_out;
output [15:0] data_out;
// control interface
input dcfilt_enb;
input [15:0] dcfilt_coeff;
input [15:0] dcfilt_offset;
// internal registers
reg [15:0] dc_offset = 'd0;
reg valid_d = 'd0;
reg [15:0] data_d = 'd0;
reg valid_out = 'd0;
reg [15:0] data_out = 'd0;
// internal signals
wire [32:0] dc_offset_33_s;
// cancelling the dc offset
always @(posedge clk) begin
dc_offset <= dc_offset_33_s[32:17];
valid_d <= valid;
if (valid == 1'b1) begin
data_d <= data + dcfilt_offset;
end
if (dcfilt_enb == 1'b1) begin
valid_out <= valid_d;
data_out <= data_d - dc_offset;
end else begin
valid_out <= valid_d;
data_out <= data_d;
end
end
ad_dcfilter_1 i_dcfilter_1 (
.clk (clk),
.d (data_d),
.b (dcfilt_coeff),
.a (dc_offset_33_s[32:17]),
.c (dc_offset_33_s[32:17]),
.p (dc_offset_33_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>xilinx.com</spirit:vendor>
<spirit:library>xci</spirit:library>
<spirit:name>unknown</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:componentInstances>
<spirit:componentInstance>
<spirit:instanceName>ad_dcfilter_1</spirit:instanceName>
<spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="xbip_dsp48_macro" spirit:version="3.0"/>
<spirit:configurableElementValues>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">ad_dcfilter_1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.GUI_Behaviour">Coregen</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.show_filtered">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction2">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction3">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction4">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction5">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction6">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction7">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction8">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction_list">#</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.instruction1">(D-A)*B+C</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.pipeline_options">Expert</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_3">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_4">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_5">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.tier_6">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.dreg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.dreg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.dreg_3">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.areg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.areg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.areg_3">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.areg_4">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.breg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.breg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.breg_3">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.breg_4">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.creg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.creg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.creg_3">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.creg_4">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.creg_5">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.concatreg_3">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.concatreg_4">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.concatreg_5">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.opreg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.opreg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.opreg_3">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.opreg_4">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.opreg_5">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.cinreg_1">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.cinreg_2">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.cinreg_3">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.cinreg_4">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.cinreg_5">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.mreg_5">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.preg_6">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.d_width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.d_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.a_width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.a_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.b_width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.b_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.concat_width">48</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.concat_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.c_width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.c_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.pcin_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.output_properties">Full_Precision</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.p_full_width">33</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.p_width">33</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.p_binarywidth">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_carryout">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_acout">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_bcout">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_carrycascout">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_pcout">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_d_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_a_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_b_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_c_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_concat_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_m_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_p_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_sel_ce">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_d_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_a_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_b_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_c_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_concat_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_m_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_p_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.has_sel_sclr">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.use_dsp48">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_VERBOSITY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_MODEL_TYPE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_XDEVICEFAMILY">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_INDEP_CE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CED">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CEA">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CEB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CEC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CECONCAT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CEM">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CESEL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLR">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_INDEP_SCLR">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRD">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRA">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRM">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRCONCAT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SCLRSEL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CARRYCASCIN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CARRYIN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ACIN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_BCIN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_PCIN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_A">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_B">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_D">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CONCAT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_C">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_A_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_B_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_C_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_D_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CONCAT_WIDTH">48</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_P_MSB">32</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_P_LSB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_SEL_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ACOUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_BCOUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CARRYCASCOUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_CARRYOUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_PCOUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CONSTANT_1">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_LATENCY">128</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OPMODES">0000001101010011000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_REG_CONFIG">00000000000011110011100011000100</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_TEST_CORE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xc7z020</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">clg484</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE">C</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VERILOG</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USER_REPO_PATHS"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD"/>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2013.2</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">GLOBAL</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue>
</spirit:configurableElementValues>
</spirit:componentInstance>
</spirit:componentInstances>
</spirit:design>

File diff suppressed because it is too large Load Diff

71
library/common/ad_dds_1.v Normal file
View File

@ -0,0 +1,71 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_dds_1 (
// interface
clk,
sclr,
phase_in,
sine);
// interface
input clk;
input sclr;
input [15:0] phase_in;
output [15:0] sine;
// xilinx dds ip
ad_dds_1_xip i_dds_1_xip (
.aclk (clk),
.aresetn (~sclr),
.s_axis_phase_tvalid (1'b1),
.s_axis_phase_tdata (phase_in),
.m_axis_data_tvalid (),
.m_axis_data_tdata (sine));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>xilinx.com</spirit:vendor>
<spirit:library>xci</spirit:library>
<spirit:name>unknown</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:componentInstances>
<spirit:componentInstance>
<spirit:instanceName>ad_dds_1_xip</spirit:instanceName>
<spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="dds_compiler" spirit:version="6.0"/>
<spirit:configurableElementValues>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">ad_dds_1_xip</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PartsPresent">SIN_COS_LUT_only</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.DDS_Clock_Rate">100</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Channels">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Mode_of_Operation">Standard</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Modulus">9</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Parameter_Entry">Hardware_Parameters</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Spurious_Free_Dynamic_Range">45</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Frequency_Resolution">0.4</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Noise_Shaping">None</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Width">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Increment">Fixed</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Resync">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_offset">None</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Selection">Sine</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Negative_Sine">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Negative_Cosine">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Amplitude_Mode">Full_Range</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Memory_Type">Auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Optimization_Goal">Auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.DSP48_Use">Minimal</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Has_Phase_Out">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.DATA_Has_TLAST">Not_Required</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Has_TREADY">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.S_PHASE_Has_TUSER">Not_Required</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.S_PHASE_TUSER_Width">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.M_DATA_Has_TUSER">Not_Required</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.M_PHASE_Has_TUSER">Not_Required</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.S_CONFIG_Sync_Mode">On_Vector</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.OUTPUT_FORM">Twos_Complement</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Latency_Configuration">Auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Latency">6</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Has_ARESETn">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Has_ACLKEN">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency1">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC1">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles1">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF1">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency2">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC2">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles2">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF2">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency3">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC3">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles3">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF3">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency4">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC4">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles4">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF4">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency5">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC5">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles5">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF5">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency6">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC6">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles6">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF6">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency7">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC7">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles7">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF7">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency8">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC8">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles8">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF8">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency9">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC9">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles9">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF9">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency10">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC10">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles10">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF10">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency11">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC11">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles11">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF11">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency12">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC12">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles12">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF12">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency13">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC13">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles13">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF13">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency14">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC14">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles14">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF14">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency15">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC15">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles15">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF15">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Output_Frequency16">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PINC16">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Phase_Offset_Angles16">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POFF16">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.POR_mode">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.GUI_Behaviour">Coregen</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.explicit_period">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.period">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_XDEVICEFAMILY">virtex7</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_MODE_OF_OPERATION">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_MODULUS">9</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_ACCUMULATOR_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CHANNELS">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_PHASE_OUT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_PHASEGEN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_SINCOS">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_LATENCY">6</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_MEM_TYPE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_NEGATIVE_COSINE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_NEGATIVE_SINE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_NOISE_SHAPING">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OUTPUTS_REQUIRED">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OUTPUT_FORM">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OUTPUT_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHASE_ANGLE_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHASE_INCREMENT">2</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHASE_INCREMENT_VALUE">0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_RESYNC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHASE_OFFSET">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHASE_OFFSET_VALUE">0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OPTIMISE_GOAL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_USE_DSP48">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_POR_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AMPLITUDE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ACLKEN">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ARESETN">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_TLAST">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_TREADY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_PHASE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_PHASE_TDATA_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_PHASE_HAS_TUSER">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_PHASE_TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_CONFIG">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_CONFIG_SYNC_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_CONFIG_TDATA_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_M_DATA">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_DATA_TDATA_WIDTH">16</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_DATA_HAS_TUSER">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_DATA_TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_M_PHASE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_PHASE_TDATA_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_PHASE_HAS_TUSER">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_PHASE_TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_DEBUG_INTERFACE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_CHAN_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">kintex7</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xc7k325t</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">ffg900</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-2</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE">C</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VERILOG</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USER_REPO_PATHS"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD"/>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2013.4</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">OUT_OF_CONTEXT</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue>
</spirit:configurableElementValues>
</spirit:componentInstance>
</spirit:componentInstances>
</spirit:design>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,751 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/1ps
module ad_gt_channel_1 (
// rst and clocks
ref_clk,
cpll_pd,
cpll_rst,
qpll_clk,
qpll_ref_clk,
qpll_locked,
// receive
rx_rst,
rx_p,
rx_n,
rx_sys_clk_sel,
rx_out_clk_sel,
rx_out_clk,
rx_rst_done,
rx_pll_locked,
rx_clk,
rx_charisk,
rx_disperr,
rx_notintable,
rx_data,
rx_comma_align_enb,
// transmit
tx_rst,
tx_p,
tx_n,
tx_sys_clk_sel,
tx_out_clk_sel,
tx_out_clk,
tx_rst_done,
tx_pll_locked,
tx_clk,
tx_charisk,
tx_data,
// drp interface
drp_clk,
drp_sel,
drp_addr,
drp_wr,
drp_wdata,
drp_rdata,
drp_ready,
drp_lanesel,
drp_rx_rate,
// monitor signals
rx_mon_trigger,
rx_mon_data);
// parameters
parameter DRP_ID = 0;
parameter CPLL_FBDIV = 2;
parameter RX_OUT_DIV = 1;
parameter TX_OUT_DIV = 1;
parameter RX_CLK25_DIV = 10;
parameter TX_CLK25_DIV = 10;
parameter PMA_RSV = 32'h00018480;
parameter RX_CDR_CFG = 72'h03000023ff20400020;
// rst and clocks
input ref_clk;
input cpll_pd;
input cpll_rst;
input qpll_clk;
input qpll_ref_clk;
input qpll_locked;
// receive
input rx_rst;
input rx_p;
input rx_n;
input [ 1:0] rx_sys_clk_sel;
input [ 2:0] rx_out_clk_sel;
output rx_out_clk;
output rx_rst_done;
output rx_pll_locked;
input rx_clk;
output [ 3:0] rx_charisk;
output [ 3:0] rx_disperr;
output [ 3:0] rx_notintable;
output [31:0] rx_data;
input rx_comma_align_enb;
// transmit
input tx_rst;
output tx_p;
output tx_n;
input [ 1:0] tx_sys_clk_sel;
input [ 2:0] tx_out_clk_sel;
output tx_out_clk;
output tx_rst_done;
output tx_pll_locked;
input tx_clk;
input [ 3:0] tx_charisk;
input [31:0] tx_data;
// drp interface
input drp_clk;
input drp_sel;
input [11:0] drp_addr;
input drp_wr;
input [15:0] drp_wdata;
output [15:0] drp_rdata;
output drp_ready;
input [ 7:0] drp_lanesel;
output [ 7:0] drp_rx_rate;
// monitor signals
output rx_mon_trigger;
output [49:0] rx_mon_data;
// internal registers
reg [ 3:0] rx_user_ready = 'd0;
reg [ 3:0] tx_user_ready = 'd0;
reg drp_sel_int = 'd0;
reg [11:0] drp_addr_int = 'd0;
reg drp_wr_int = 'd0;
reg [15:0] drp_wdata_int = 'd0;
reg [15:0] drp_rdata = 'd0;
reg drp_ready = 'd0;
reg [ 7:0] drp_rx_rate = 'd0;
// internal signals
wire rx_ilas_f_s;
wire rx_ilas_q_s;
wire rx_ilas_a_s;
wire rx_ilas_r_s;
wire rx_cgs_k_s;
wire [ 3:0] rx_valid_k_s;
wire rx_valid_k_1_s;
wire [ 2:0] rx_rate_p_s;
wire [ 7:0] rx_rate_s;
wire [ 3:0] rx_charisk_open_s;
wire [ 3:0] rx_disperr_open_s;
wire [ 3:0] rx_notintable_open_s;
wire [31:0] rx_data_open_s;
wire cpll_locked_s;
wire [15:0] drp_rdata_s;
wire drp_ready_s;
// monitor interface
assign rx_mon_data[31: 0] = rx_data;
assign rx_mon_data[35:32] = rx_notintable;
assign rx_mon_data[39:36] = rx_disperr;
assign rx_mon_data[43:40] = rx_charisk;
assign rx_mon_data[44:44] = rx_valid_k_1_s;
assign rx_mon_data[45:45] = rx_cgs_k_s;
assign rx_mon_data[46:46] = rx_ilas_r_s;
assign rx_mon_data[47:47] = rx_ilas_a_s;
assign rx_mon_data[48:48] = rx_ilas_q_s;
assign rx_mon_data[49:49] = rx_ilas_f_s;
assign rx_mon_trigger = rx_valid_k_1_s;
// ilas frame characters
assign rx_ilas_f_s =
(((rx_data[31:24] == 8'hfc) && (rx_valid_k_s[ 3] == 1'b1)) ||
((rx_data[23:16] == 8'hfc) && (rx_valid_k_s[ 2] == 1'b1)) ||
((rx_data[15: 8] == 8'hfc) && (rx_valid_k_s[ 1] == 1'b1)) ||
((rx_data[ 7: 0] == 8'hfc) && (rx_valid_k_s[ 0] == 1'b1))) ? 1'b1 : 1'b0;
assign rx_ilas_q_s =
(((rx_data[31:24] == 8'h9c) && (rx_valid_k_s[ 3] == 1'b1)) ||
((rx_data[23:16] == 8'h9c) && (rx_valid_k_s[ 2] == 1'b1)) ||
((rx_data[15: 8] == 8'h9c) && (rx_valid_k_s[ 1] == 1'b1)) ||
((rx_data[ 7: 0] == 8'h9c) && (rx_valid_k_s[ 0] == 1'b1))) ? 1'b1 : 1'b0;
assign rx_ilas_a_s =
(((rx_data[31:24] == 8'h7c) && (rx_valid_k_s[ 3] == 1'b1)) ||
((rx_data[23:16] == 8'h7c) && (rx_valid_k_s[ 2] == 1'b1)) ||
((rx_data[15: 8] == 8'h7c) && (rx_valid_k_s[ 1] == 1'b1)) ||
((rx_data[ 7: 0] == 8'h7c) && (rx_valid_k_s[ 0] == 1'b1))) ? 1'b1 : 1'b0;
assign rx_ilas_r_s =
(((rx_data[31:24] == 8'h1c) && (rx_valid_k_s[ 3] == 1'b1)) ||
((rx_data[23:16] == 8'h1c) && (rx_valid_k_s[ 2] == 1'b1)) ||
((rx_data[15: 8] == 8'h1c) && (rx_valid_k_s[ 1] == 1'b1)) ||
((rx_data[ 7: 0] == 8'h1c) && (rx_valid_k_s[ 0] == 1'b1))) ? 1'b1 : 1'b0;
assign rx_cgs_k_s =
(((rx_data[31:24] == 8'hbc) && (rx_valid_k_s[ 3] == 1'b1)) &&
((rx_data[23:16] == 8'hbc) && (rx_valid_k_s[ 2] == 1'b1)) &&
((rx_data[15: 8] == 8'hbc) && (rx_valid_k_s[ 1] == 1'b1)) &&
((rx_data[ 7: 0] == 8'hbc) && (rx_valid_k_s[ 0] == 1'b1))) ? 1'b1 : 1'b0;
// validate all characters
assign rx_valid_k_s = rx_charisk & (~rx_disperr) & (~rx_notintable);
assign rx_valid_k_1_s = (rx_valid_k_s == 4'd0) ? 1'b0 : 1'b1;
// rate
assign rx_rate_p_s = 0;
assign rx_rate_s = (rx_rate_p_s == 3'd0) ? RX_OUT_DIV :
(rx_rate_p_s == 3'd1) ? 8'h01 :
(rx_rate_p_s == 3'd2) ? 8'h02 :
(rx_rate_p_s == 3'd3) ? 8'h04 :
(rx_rate_p_s == 3'd4) ? 8'h08 :
(rx_rate_p_s == 3'd5) ? 8'h10 : 8'h00;
// pll locked
assign rx_pll_locked = (rx_sys_clk_sel[0] == 1'b1) ? qpll_locked : cpll_locked_s;
assign tx_pll_locked = (tx_sys_clk_sel[0] == 1'b1) ? qpll_locked : cpll_locked_s;
// user ready
always @(posedge rx_clk or posedge rx_rst) begin
if (rx_rst == 1'b1) begin
rx_user_ready <= 4'd0;
end else begin
rx_user_ready <= {rx_user_ready[2:0], 1'b1};
end
end
always @(posedge tx_clk or posedge tx_rst) begin
if (tx_rst == 1'b1) begin
tx_user_ready <= 4'd0;
end else begin
tx_user_ready <= {tx_user_ready[2:0], 1'b1};
end
end
// drp control
always @(posedge drp_clk) begin
if (drp_lanesel == DRP_ID) begin
drp_sel_int <= drp_sel;
drp_addr_int <= drp_addr;
drp_wr_int <= drp_wr;
drp_wdata_int <= drp_wdata;
drp_rdata <= drp_rdata_s;
drp_ready <= drp_ready_s;
drp_rx_rate <= rx_rate_s;
end else begin
drp_sel_int <= 1'd0;
drp_addr_int <= 12'd0;
drp_wr_int <= 1'd0;
drp_wdata_int <= 16'd0;
drp_rdata <= 16'd0;
drp_ready <= 1'd0;
drp_rx_rate <= 8'd0;
end
end
// instantiations
GTXE2_CHANNEL #(
.SIM_RECEIVER_DETECT_PASS ("TRUE"),
.SIM_TX_EIDLE_DRIVE_LEVEL ("X"),
.SIM_RESET_SPEEDUP ("TRUE"),
.SIM_CPLLREFCLK_SEL (3'b001),
.SIM_VERSION ("3.0"),
.ALIGN_COMMA_DOUBLE ("FALSE"),
.ALIGN_COMMA_ENABLE (10'b1111111111),
.ALIGN_COMMA_WORD (1),
.ALIGN_MCOMMA_DET ("TRUE"),
.ALIGN_MCOMMA_VALUE (10'b1010000011),
.ALIGN_PCOMMA_DET ("TRUE"),
.ALIGN_PCOMMA_VALUE (10'b0101111100),
.SHOW_REALIGN_COMMA ("TRUE"),
.RXSLIDE_AUTO_WAIT (7),
.RXSLIDE_MODE ("OFF"),
.RX_SIG_VALID_DLY (10),
.RX_DISPERR_SEQ_MATCH ("TRUE"),
.DEC_MCOMMA_DETECT ("TRUE"),
.DEC_PCOMMA_DETECT ("TRUE"),
.DEC_VALID_COMMA_ONLY ("FALSE"),
.CBCC_DATA_SOURCE_SEL ("DECODED"),
.CLK_COR_SEQ_2_USE ("FALSE"),
.CLK_COR_KEEP_IDLE ("FALSE"),
.CLK_COR_MAX_LAT (35),
.CLK_COR_MIN_LAT (31),
.CLK_COR_PRECEDENCE ("TRUE"),
.CLK_COR_REPEAT_WAIT (0),
.CLK_COR_SEQ_LEN (1),
.CLK_COR_SEQ_1_ENABLE (4'b1111),
.CLK_COR_SEQ_1_1 (10'b0000000000),
.CLK_COR_SEQ_1_2 (10'b0000000000),
.CLK_COR_SEQ_1_3 (10'b0000000000),
.CLK_COR_SEQ_1_4 (10'b0000000000),
.CLK_CORRECT_USE ("FALSE"),
.CLK_COR_SEQ_2_ENABLE (4'b1111),
.CLK_COR_SEQ_2_1 (10'b0000000000),
.CLK_COR_SEQ_2_2 (10'b0000000000),
.CLK_COR_SEQ_2_3 (10'b0000000000),
.CLK_COR_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_KEEP_ALIGN ("FALSE"),
.CHAN_BOND_MAX_SKEW (7),
.CHAN_BOND_SEQ_LEN (1),
.CHAN_BOND_SEQ_1_1 (10'b0000000000),
.CHAN_BOND_SEQ_1_2 (10'b0000000000),
.CHAN_BOND_SEQ_1_3 (10'b0000000000),
.CHAN_BOND_SEQ_1_4 (10'b0000000000),
.CHAN_BOND_SEQ_1_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_1 (10'b0000000000),
.CHAN_BOND_SEQ_2_2 (10'b0000000000),
.CHAN_BOND_SEQ_2_3 (10'b0000000000),
.CHAN_BOND_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_SEQ_2_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_USE ("FALSE"),
.FTS_DESKEW_SEQ_ENABLE (4'b1111),
.FTS_LANE_DESKEW_CFG (4'b1111),
.FTS_LANE_DESKEW_EN ("FALSE"),
.ES_CONTROL (6'b000000),
.ES_ERRDET_EN ("TRUE"),
.ES_EYE_SCAN_EN ("TRUE"),
.ES_HORZ_OFFSET (12'h000),
.ES_PMA_CFG (10'b0000000000),
.ES_PRESCALE (5'b00000),
.ES_QUALIFIER (80'h00000000000000000000),
.ES_QUAL_MASK (80'h00000000000000000000),
.ES_SDATA_MASK (80'h00000000000000000000),
.ES_VERT_OFFSET (9'b000000000),
.RX_DATA_WIDTH (40),
.OUTREFCLK_SEL_INV (2'b11),
.PMA_RSV (PMA_RSV),
.PMA_RSV2 (16'h2070),
.PMA_RSV3 (2'b00),
.PMA_RSV4 (32'h00000000),
.RX_BIAS_CFG (12'b000000000100),
.DMONITOR_CFG (24'h000A00),
.RX_CM_SEL (2'b11),
.RX_CM_TRIM (3'b010),
.RX_DEBUG_CFG (12'b000000000000),
.RX_OS_CFG (13'b0000010000000),
.TERM_RCAL_CFG (5'b10000),
.TERM_RCAL_OVRD (1'b0),
.TST_RSV (32'h00000000),
.RX_CLK25_DIV (RX_CLK25_DIV),
.TX_CLK25_DIV (TX_CLK25_DIV),
.UCODEER_CLR (1'b0),
.PCS_PCIE_EN ("FALSE"),
.PCS_RSVD_ATTR (48'h000000000000),
.RXBUF_ADDR_MODE ("FULL"),
.RXBUF_EIDLE_HI_CNT (4'b1000),
.RXBUF_EIDLE_LO_CNT (4'b0000),
.RXBUF_EN ("TRUE"),
.RX_BUFFER_CFG (6'b000000),
.RXBUF_RESET_ON_CB_CHANGE ("TRUE"),
.RXBUF_RESET_ON_COMMAALIGN ("FALSE"),
.RXBUF_RESET_ON_EIDLE ("FALSE"),
.RXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.RXBUFRESET_TIME (5'b00001),
.RXBUF_THRESH_OVFLW (61),
.RXBUF_THRESH_OVRD ("FALSE"),
.RXBUF_THRESH_UNDFLW (4),
.RXDLY_CFG (16'h001F),
.RXDLY_LCFG (9'h030),
.RXDLY_TAP_CFG (16'h0000),
.RXPH_CFG (24'h000000),
.RXPHDLY_CFG (24'h084020),
.RXPH_MONITOR_SEL (5'b00000),
.RX_XCLK_SEL ("RXREC"),
.RX_DDI_SEL (6'b000000),
.RX_DEFER_RESET_BUF_EN ("TRUE"),
.RXCDR_CFG (RX_CDR_CFG),
.RXCDR_FR_RESET_ON_EIDLE (1'b0),
.RXCDR_HOLD_DURING_EIDLE (1'b0),
.RXCDR_PH_RESET_ON_EIDLE (1'b0),
.RXCDR_LOCK_CFG (6'b010101),
.RXCDRFREQRESET_TIME (5'b00001),
.RXCDRPHRESET_TIME (5'b00001),
.RXISCANRESET_TIME (5'b00001),
.RXPCSRESET_TIME (5'b00001),
.RXPMARESET_TIME (5'b00011),
.RXOOB_CFG (7'b0000110),
.RXGEARBOX_EN ("FALSE"),
.GEARBOX_MODE (3'b000),
.RXPRBS_ERR_LOOPBACK (1'b0),
.PD_TRANS_TIME_FROM_P2 (12'h03c),
.PD_TRANS_TIME_NONE_P2 (8'h3c),
.PD_TRANS_TIME_TO_P2 (8'h64),
.SAS_MAX_COM (64),
.SAS_MIN_COM (36),
.SATA_BURST_SEQ_LEN (4'b1111),
.SATA_BURST_VAL (3'b100),
.SATA_EIDLE_VAL (3'b100),
.SATA_MAX_BURST (8),
.SATA_MAX_INIT (21),
.SATA_MAX_WAKE (7),
.SATA_MIN_BURST (4),
.SATA_MIN_INIT (12),
.SATA_MIN_WAKE (4),
.TRANS_TIME_RATE (8'h0E),
.TXBUF_EN ("TRUE"),
.TXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.TXDLY_CFG (16'h001F),
.TXDLY_LCFG (9'h030),
.TXDLY_TAP_CFG (16'h0000),
.TXPH_CFG (16'h0780),
.TXPHDLY_CFG (24'h084020),
.TXPH_MONITOR_SEL (5'b00000),
.TX_XCLK_SEL ("TXOUT"),
.TX_DATA_WIDTH (40),
.TX_DEEMPH0 (5'b00000),
.TX_DEEMPH1 (5'b00000),
.TX_EIDLE_ASSERT_DELAY (3'b110),
.TX_EIDLE_DEASSERT_DELAY (3'b100),
.TX_LOOPBACK_DRIVE_HIZ ("FALSE"),
.TX_MAINCURSOR_SEL (1'b0),
.TX_DRIVE_MODE ("DIRECT"),
.TX_MARGIN_FULL_0 (7'b1001110),
.TX_MARGIN_FULL_1 (7'b1001001),
.TX_MARGIN_FULL_2 (7'b1000101),
.TX_MARGIN_FULL_3 (7'b1000010),
.TX_MARGIN_FULL_4 (7'b1000000),
.TX_MARGIN_LOW_0 (7'b1000110),
.TX_MARGIN_LOW_1 (7'b1000100),
.TX_MARGIN_LOW_2 (7'b1000010),
.TX_MARGIN_LOW_3 (7'b1000000),
.TX_MARGIN_LOW_4 (7'b1000000),
.TXGEARBOX_EN ("FALSE"),
.TXPCSRESET_TIME (5'b00001),
.TXPMARESET_TIME (5'b00001),
.TX_RXDETECT_CFG (14'h1832),
.TX_RXDETECT_REF (3'b100),
.CPLL_CFG (24'hBC07DC),
.CPLL_FBDIV (CPLL_FBDIV),
.CPLL_FBDIV_45 (5),
.CPLL_INIT_CFG (24'h00001E),
.CPLL_LOCK_CFG (16'h01E8),
.CPLL_REFCLK_DIV (1),
.RXOUT_DIV (RX_OUT_DIV),
.TXOUT_DIV (TX_OUT_DIV),
.SATA_CPLL_CFG ("VCO_3000MHZ"),
.RXDFELPMRESET_TIME (7'b0001111),
.RXLPM_HF_CFG (14'b00000011110000),
.RXLPM_LF_CFG (14'b00000011110000),
.RX_DFE_GAIN_CFG (23'h020FEA),
.RX_DFE_H2_CFG (12'b000000000000),
.RX_DFE_H3_CFG (12'b000001000000),
.RX_DFE_H4_CFG (11'b00011110000),
.RX_DFE_H5_CFG (11'b00011100000),
.RX_DFE_KL_CFG (13'b0000011111110),
.RX_DFE_LPM_CFG (16'h0954),
.RX_DFE_LPM_HOLD_DURING_EIDLE (1'b0),
.RX_DFE_UT_CFG (17'b10001111000000000),
.RX_DFE_VP_CFG (17'b00011111100000011),
.RX_CLKMUX_PD (1'b1),
.TX_CLKMUX_PD (1'b1),
.RX_INT_DATAWIDTH (1),
.TX_INT_DATAWIDTH (1),
.TX_QPI_STATUS_EN (1'b0),
.RX_DFE_KL_CFG2 (32'h3010D90C),
.RX_DFE_XYD_CFG (13'b0001100010000),
.TX_PREDRIVER_MODE (1'b0))
i_gtxe2_channel (
.CPLLFBCLKLOST (),
.CPLLLOCK (cpll_locked_s),
.CPLLLOCKDETCLK (drp_clk),
.CPLLLOCKEN (1'd1),
.CPLLPD (cpll_pd),
.CPLLREFCLKLOST (),
.CPLLREFCLKSEL (3'b001),
.CPLLRESET (cpll_rst),
.GTRSVD (16'b0000000000000000),
.PCSRSVDIN (16'b0000000000000000),
.PCSRSVDIN2 (5'b00000),
.PMARSVDIN (5'b00000),
.PMARSVDIN2 (5'b00000),
.TSTIN (20'b11111111111111111111),
.TSTOUT (),
.CLKRSVD (4'b0000),
.GTGREFCLK (1'd0),
.GTNORTHREFCLK0 (1'd0),
.GTNORTHREFCLK1 (1'd0),
.GTREFCLK0 (ref_clk),
.GTREFCLK1 (1'd0),
.GTSOUTHREFCLK0 (1'd0),
.GTSOUTHREFCLK1 (1'd0),
.DRPADDR (drp_addr_int[8:0]),
.DRPCLK (drp_clk),
.DRPDI (drp_wdata_int),
.DRPDO (drp_rdata_s),
.DRPEN (drp_sel_int),
.DRPRDY (drp_ready_s),
.DRPWE (drp_wr_int),
.GTREFCLKMONITOR (),
.QPLLCLK (qpll_clk),
.QPLLREFCLK (qpll_ref_clk),
.RXSYSCLKSEL (rx_sys_clk_sel),
.TXSYSCLKSEL (tx_sys_clk_sel),
.DMONITOROUT (),
.TX8B10BEN (1'd1),
.LOOPBACK (3'd0),
.PHYSTATUS (),
.RXRATE (rx_rate_p_s),
.RXVALID (),
.RXPD (2'b00),
.TXPD (2'b00),
.SETERRSTATUS (1'd0),
.EYESCANRESET (1'd0),
.RXUSERRDY (rx_user_ready[3]),
.EYESCANDATAERROR (),
.EYESCANMODE (1'd0),
.EYESCANTRIGGER (1'd0),
.RXCDRFREQRESET (1'd0),
.RXCDRHOLD (1'd0),
.RXCDRLOCK (),
.RXCDROVRDEN (1'd0),
.RXCDRRESET (1'd0),
.RXCDRRESETRSV (1'd0),
.RXCLKCORCNT (),
.RX8B10BEN (1'd1),
.RXUSRCLK (rx_clk),
.RXUSRCLK2 (rx_clk),
.RXDATA ({rx_data_open_s, rx_data}),
.RXPRBSERR (),
.RXPRBSSEL (3'd0),
.RXPRBSCNTRESET (1'd0),
.RXDFEXYDEN (1'd0),
.RXDFEXYDHOLD (1'd0),
.RXDFEXYDOVRDEN (1'd0),
.RXDISPERR ({rx_disperr_open_s, rx_disperr}),
.RXNOTINTABLE ({rx_notintable_open_s, rx_notintable}),
.GTXRXP (rx_p),
.GTXRXN (rx_n),
.RXBUFRESET (1'd0),
.RXBUFSTATUS (),
.RXDDIEN (1'd0),
.RXDLYBYPASS (1'd1),
.RXDLYEN (1'd0),
.RXDLYOVRDEN (1'd0),
.RXDLYSRESET (1'd0),
.RXDLYSRESETDONE (),
.RXPHALIGN (1'd0),
.RXPHALIGNDONE (),
.RXPHALIGNEN (1'd0),
.RXPHDLYPD (1'd0),
.RXPHDLYRESET (1'd0),
.RXPHMONITOR (),
.RXPHOVRDEN (1'd0),
.RXPHSLIPMONITOR (),
.RXSTATUS (),
.RXBYTEISALIGNED (),
.RXBYTEREALIGN (),
.RXCOMMADET (),
.RXCOMMADETEN (1'd1),
.RXMCOMMAALIGNEN (rx_comma_align_enb),
.RXPCOMMAALIGNEN (rx_comma_align_enb),
.RXCHANBONDSEQ (),
.RXCHBONDEN (1'd0),
.RXCHBONDLEVEL (3'd0),
.RXCHBONDMASTER (1'd1),
.RXCHBONDO (),
.RXCHBONDSLAVE (1'd0),
.RXCHANISALIGNED (),
.RXCHANREALIGN (),
.RXDFEAGCHOLD (1'd0),
.RXDFEAGCOVRDEN (1'd0),
.RXDFECM1EN (1'd0),
.RXDFELFHOLD (1'd0),
.RXDFELFOVRDEN (1'd1),
.RXDFELPMRESET (1'd0),
.RXDFETAP2HOLD (1'd0),
.RXDFETAP2OVRDEN (1'd0),
.RXDFETAP3HOLD (1'd0),
.RXDFETAP3OVRDEN (1'd0),
.RXDFETAP4HOLD (1'd0),
.RXDFETAP4OVRDEN (1'd0),
.RXDFETAP5HOLD (1'd0),
.RXDFETAP5OVRDEN (1'd0),
.RXDFEUTHOLD (1'd0),
.RXDFEUTOVRDEN (1'd0),
.RXDFEVPHOLD (1'd0),
.RXDFEVPOVRDEN (1'd0),
.RXDFEVSEN (1'd0),
.RXLPMLFKLOVRDEN (1'd0),
.RXMONITOROUT (),
.RXMONITORSEL (2'd0),
.RXOSHOLD (1'd0),
.RXOSOVRDEN (1'd0),
.RXLPMHFHOLD (1'd0),
.RXLPMHFOVRDEN (1'd0),
.RXLPMLFHOLD (1'd0),
.RXRATEDONE (),
.RXOUTCLK (rx_out_clk),
.RXOUTCLKFABRIC (),
.RXOUTCLKPCS (),
.RXOUTCLKSEL (rx_out_clk_sel),
.RXDATAVALID (),
.RXHEADER (),
.RXHEADERVALID (),
.RXSTARTOFSEQ (),
.RXGEARBOXSLIP (1'd0),
.GTRXRESET (rx_rst),
.RXOOBRESET (1'd0),
.RXPCSRESET (1'd0),
.RXPMARESET (1'd0),
.RXLPMEN (1'd0),
.RXCOMSASDET (),
.RXCOMWAKEDET (),
.RXCOMINITDET (),
.RXELECIDLE (),
.RXELECIDLEMODE (2'b10),
.RXPOLARITY (1'd0),
.RXSLIDE (1'd0),
.RXCHARISCOMMA (),
.RXCHARISK ({rx_charisk_open_s, rx_charisk}),
.RXCHBONDI (5'd0),
.RXRESETDONE (rx_rst_done),
.RXQPIEN (1'd0),
.RXQPISENN (),
.RXQPISENP (),
.TXPHDLYTSTCLK (1'd0),
.TXPOSTCURSOR (5'd0),
.TXPOSTCURSORINV (1'd0),
.TXPRECURSOR (5'd0),
.TXPRECURSORINV (1'd0),
.TXQPIBIASEN (1'd0),
.TXQPISTRONGPDOWN (1'd0),
.TXQPIWEAKPUP (1'd0),
.CFGRESET (1'd0),
.GTTXRESET (tx_rst),
.PCSRSVDOUT (),
.TXUSERRDY (tx_user_ready[3]),
.GTRESETSEL (1'd0),
.RESETOVRD (1'd0),
.TXCHARDISPMODE (8'd0),
.TXCHARDISPVAL (8'd0),
.TXUSRCLK (tx_clk),
.TXUSRCLK2 (tx_clk),
.TXELECIDLE (1'd0),
.TXMARGIN (3'd0),
.TXRATE (3'd0),
.TXSWING (1'd0),
.TXPRBSFORCEERR (1'd0),
.TXDLYBYPASS (1'd1),
.TXDLYEN (1'd0),
.TXDLYHOLD (1'd0),
.TXDLYOVRDEN (1'd0),
.TXDLYSRESET (1'd0),
.TXDLYSRESETDONE (),
.TXDLYUPDOWN (1'd0),
.TXPHALIGN (1'd0),
.TXPHALIGNDONE (),
.TXPHALIGNEN (1'd0),
.TXPHDLYPD (1'd0),
.TXPHDLYRESET (1'd0),
.TXPHINIT (1'd0),
.TXPHINITDONE (),
.TXPHOVRDEN (1'd0),
.TXBUFSTATUS (),
.TXBUFDIFFCTRL (3'b100),
.TXDEEMPH (1'd0),
.TXDIFFCTRL (4'b1000),
.TXDIFFPD (1'd0),
.TXINHIBIT (1'd0),
.TXMAINCURSOR (7'b0000000),
.TXPISOPD (1'd0),
.TXDATA ({32'd0, tx_data}),
.GTXTXP (tx_p),
.GTXTXN (tx_n),
.TXOUTCLK (tx_out_clk),
.TXOUTCLKFABRIC (),
.TXOUTCLKPCS (),
.TXOUTCLKSEL (tx_out_clk_sel),
.TXRATEDONE (),
.TXCHARISK ({4'd0, tx_charisk}),
.TXGEARBOXREADY (),
.TXHEADER (3'd0),
.TXSEQUENCE (7'd0),
.TXSTARTSEQ (1'd0),
.TXPCSRESET (1'd0),
.TXPMARESET (1'd0),
.TXRESETDONE (tx_rst_done),
.TXCOMFINISH (),
.TXCOMINIT (1'd0),
.TXCOMSAS (1'd0),
.TXCOMWAKE (1'd0),
.TXPDELECIDLEMODE (1'd0),
.TXPOLARITY (1'd0),
.TXDETECTRX (1'd0),
.TX8B10BBYPASS (8'd0),
.TXPRBSSEL (3'd0),
.TXQPISENP (),
.TXQPISENN ());
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,190 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/1ps
module ad_gt_common_1 (
// reset and clocks
rst,
ref_clk,
qpll_clk,
qpll_ref_clk,
qpll_locked,
// drp interface
drp_clk,
drp_sel,
drp_addr,
drp_wr,
drp_wdata,
drp_rdata,
drp_ready,
drp_lanesel,
drp_rx_rate);
// parameters
parameter DRP_ID = 0;
parameter QPLL_REFCLK_DIV = 2;
parameter QPLL_CFG = 27'h06801C1;
parameter QPLL_FBDIV_RATIO = 1'b1;
parameter QPLL_FBDIV = 10'b0000110000;
// reset and clocks
input rst;
input ref_clk;
output qpll_clk;
output qpll_ref_clk;
output qpll_locked;
// drp interface
input drp_clk;
input drp_sel;
input [11:0] drp_addr;
input drp_wr;
input [15:0] drp_wdata;
output [15:0] drp_rdata;
output drp_ready;
input [ 7:0] drp_lanesel;
output [ 7:0] drp_rx_rate;
// internal registers
reg drp_sel_int;
reg [11:0] drp_addr_int;
reg drp_wr_int;
reg [15:0] drp_wdata_int;
reg [15:0] drp_rdata;
reg drp_ready;
reg [ 7:0] drp_rx_rate;
// internal wires
wire [15:0] drp_rdata_s;
wire drp_ready_s;
// drp control
always @(posedge drp_clk) begin
if (drp_lanesel == DRP_ID) begin
drp_sel_int <= drp_sel;
drp_addr_int <= drp_addr;
drp_wr_int <= drp_wr;
drp_wdata_int <= drp_wdata;
drp_rdata <= drp_rdata_s;
drp_ready <= drp_ready_s;
drp_rx_rate <= 8'hff;
end else begin
drp_sel_int <= 1'd0;
drp_addr_int <= 12'd0;
drp_wr_int <= 1'd0;
drp_wdata_int <= 16'd0;
drp_rdata <= 16'd0;
drp_ready <= 1'd0;
drp_rx_rate <= 8'd0;
end
end
// instantiations
GTXE2_COMMON #(
.SIM_RESET_SPEEDUP ("TRUE"),
.SIM_QPLLREFCLK_SEL (3'b001),
.SIM_VERSION ("3.0"),
.BIAS_CFG (64'h0000040000001000),
.COMMON_CFG (32'h00000000),
.QPLL_CFG (QPLL_CFG),
.QPLL_CLKOUT_CFG (4'b0000),
.QPLL_COARSE_FREQ_OVRD (6'b010000),
.QPLL_COARSE_FREQ_OVRD_EN (1'b0),
.QPLL_CP (10'b0000011111),
.QPLL_CP_MONITOR_EN (1'b0),
.QPLL_DMONITOR_SEL (1'b0),
.QPLL_FBDIV (QPLL_FBDIV),
.QPLL_FBDIV_MONITOR_EN (1'b0),
.QPLL_FBDIV_RATIO (QPLL_FBDIV_RATIO),
.QPLL_INIT_CFG (24'h000006),
.QPLL_LOCK_CFG (16'h21E8),
.QPLL_LPF (4'b1111),
.QPLL_REFCLK_DIV (QPLL_REFCLK_DIV))
i_gtxe2_common (
.DRPCLK (drp_clk),
.DRPEN (drp_sel_int),
.DRPADDR (drp_addr_int[7:0]),
.DRPWE (drp_wr_int),
.DRPDI (drp_wdata_int),
.DRPDO (drp_rdata_s),
.DRPRDY (drp_ready_s),
.GTGREFCLK (1'd0),
.GTNORTHREFCLK0 (1'd0),
.GTNORTHREFCLK1 (1'd0),
.GTREFCLK0 (ref_clk),
.GTREFCLK1 (1'd0),
.GTSOUTHREFCLK0 (1'd0),
.GTSOUTHREFCLK1 (1'd0),
.QPLLDMONITOR (),
.QPLLOUTCLK (qpll_clk),
.QPLLOUTREFCLK (qpll_ref_clk),
.REFCLKOUTMONITOR (),
.QPLLFBCLKLOST (),
.QPLLLOCK (qpll_locked),
.QPLLLOCKDETCLK (drp_clk),
.QPLLLOCKEN (1'd1),
.QPLLOUTRESET (1'd0),
.QPLLPD (1'd0),
.QPLLREFCLKLOST (),
.QPLLREFCLKSEL (3'b001),
.QPLLRESET (rst),
.QPLLRSVD1 (16'b0000000000000000),
.QPLLRSVD2 (5'b11111),
.BGBYPASSB (1'd1),
.BGMONITORENB (1'd1),
.BGPDB (1'd1),
.BGRCALOVRD (5'b00000),
.PMARSVD (8'b00000000),
.RCALENB (1'd1));
endmodule
// ***************************************************************************
// ***************************************************************************

876
library/common/ad_gt_es.v Normal file
View File

@ -0,0 +1,876 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_gt_es (
// drp interface
drp_rst,
drp_clk,
es_sel,
es_wr,
es_addr,
es_wdata,
es_rdata,
es_ready,
// axi4 interface
axi_rstn,
axi_clk,
axi_awvalid,
axi_awaddr,
axi_awprot,
axi_awready,
axi_wvalid,
axi_wdata,
axi_wstrb,
axi_wready,
axi_bvalid,
axi_bresp,
axi_bready,
axi_arvalid,
axi_araddr,
axi_arprot,
axi_arready,
axi_rvalid,
axi_rresp,
axi_rdata,
axi_rready,
// processor interface
es_start,
es_stop,
es_init,
es_sdata0,
es_sdata1,
es_sdata2,
es_sdata3,
es_sdata4,
es_qdata0,
es_qdata1,
es_qdata2,
es_qdata3,
es_qdata4,
es_prescale,
es_hoffset_min,
es_hoffset_max,
es_hoffset_step,
es_voffset_min,
es_voffset_max,
es_voffset_step,
es_start_addr,
es_dmaerr,
es_status,
// debug interface
es_dbg_trigger,
es_dbg_data);
// parameters
parameter GTH_GTX_N = 0;
// gt address
localparam ES_DRP_CTRL_ADDR = (GTH_GTX_N == 1) ? 12'h03d : 12'h03d;
localparam ES_DRP_SDATA0_ADDR = (GTH_GTX_N == 1) ? 12'h036 : 12'h036;
localparam ES_DRP_SDATA1_ADDR = (GTH_GTX_N == 1) ? 12'h037 : 12'h037;
localparam ES_DRP_SDATA2_ADDR = (GTH_GTX_N == 1) ? 12'h038 : 12'h038;
localparam ES_DRP_SDATA3_ADDR = (GTH_GTX_N == 1) ? 12'h039 : 12'h039;
localparam ES_DRP_SDATA4_ADDR = (GTH_GTX_N == 1) ? 12'h03a : 12'h03a;
localparam ES_DRP_QDATA0_ADDR = (GTH_GTX_N == 1) ? 12'h031 : 12'h031;
localparam ES_DRP_QDATA1_ADDR = (GTH_GTX_N == 1) ? 12'h032 : 12'h032;
localparam ES_DRP_QDATA2_ADDR = (GTH_GTX_N == 1) ? 12'h033 : 12'h033;
localparam ES_DRP_QDATA3_ADDR = (GTH_GTX_N == 1) ? 12'h034 : 12'h034;
localparam ES_DRP_QDATA4_ADDR = (GTH_GTX_N == 1) ? 12'h035 : 12'h035;
localparam ES_DRP_HOFFSET_ADDR = (GTH_GTX_N == 1) ? 12'h03c : 12'h03c;
localparam ES_DRP_VOFFSET_ADDR = (GTH_GTX_N == 1) ? 12'h03b : 12'h03b;
localparam ES_DRP_STATUS_ADDR = (GTH_GTX_N == 1) ? 12'h153 : 12'h151;
localparam ES_DRP_SCNT_ADDR = (GTH_GTX_N == 1) ? 12'h152 : 12'h150;
localparam ES_DRP_ECNT_ADDR = (GTH_GTX_N == 1) ? 12'h151 : 12'h14f;
// state machine
parameter ES_FSM_IDLE = 6'h00;
parameter ES_FSM_CTRLINIT_READ = 6'h01;
parameter ES_FSM_CTRLINIT_RRDY = 6'h02;
parameter ES_FSM_CTRLINIT_WRITE = 6'h03;
parameter ES_FSM_CTRLINIT_WRDY = 6'h04;
parameter ES_FSM_SDATA0_WRITE = 6'h05;
parameter ES_FSM_SDATA0_WRDY = 6'h06;
parameter ES_FSM_SDATA1_WRITE = 6'h07;
parameter ES_FSM_SDATA1_WRDY = 6'h08;
parameter ES_FSM_SDATA2_WRITE = 6'h09;
parameter ES_FSM_SDATA2_WRDY = 6'h0a;
parameter ES_FSM_SDATA3_WRITE = 6'h0b;
parameter ES_FSM_SDATA3_WRDY = 6'h0c;
parameter ES_FSM_SDATA4_WRITE = 6'h0d;
parameter ES_FSM_SDATA4_WRDY = 6'h0e;
parameter ES_FSM_QDATA0_WRITE = 6'h0f;
parameter ES_FSM_QDATA0_WRDY = 6'h10;
parameter ES_FSM_QDATA1_WRITE = 6'h11;
parameter ES_FSM_QDATA1_WRDY = 6'h12;
parameter ES_FSM_QDATA2_WRITE = 6'h13;
parameter ES_FSM_QDATA2_WRDY = 6'h14;
parameter ES_FSM_QDATA3_WRITE = 6'h15;
parameter ES_FSM_QDATA3_WRDY = 6'h16;
parameter ES_FSM_QDATA4_WRITE = 6'h17;
parameter ES_FSM_QDATA4_WRDY = 6'h18;
parameter ES_FSM_HOFFSET_READ = 6'h19;
parameter ES_FSM_HOFFSET_RRDY = 6'h1a;
parameter ES_FSM_HOFFSET_WRITE = 6'h1b;
parameter ES_FSM_HOFFSET_WRDY = 6'h1c;
parameter ES_FSM_VOFFSET_READ = 6'h1d;
parameter ES_FSM_VOFFSET_RRDY = 6'h1e;
parameter ES_FSM_VOFFSET_WRITE = 6'h1f;
parameter ES_FSM_VOFFSET_WRDY = 6'h20;
parameter ES_FSM_CTRLSTART_READ = 6'h21;
parameter ES_FSM_CTRLSTART_RRDY = 6'h22;
parameter ES_FSM_CTRLSTART_WRITE = 6'h23;
parameter ES_FSM_CTRLSTART_WRDY = 6'h24;
parameter ES_FSM_STATUS_READ = 6'h25;
parameter ES_FSM_STATUS_RRDY = 6'h26;
parameter ES_FSM_CTRLSTOP_READ = 6'h27;
parameter ES_FSM_CTRLSTOP_RRDY = 6'h28;
parameter ES_FSM_CTRLSTOP_WRITE = 6'h29;
parameter ES_FSM_CTRLSTOP_WRDY = 6'h2a;
parameter ES_FSM_SCNT_READ = 6'h2b;
parameter ES_FSM_SCNT_RRDY = 6'h2c;
parameter ES_FSM_ECNT_READ = 6'h2d;
parameter ES_FSM_ECNT_RRDY = 6'h2e;
parameter ES_FSM_DATA = 6'h2f;
// drp interface
input drp_rst;
input drp_clk;
output es_sel;
output es_wr;
output [11:0] es_addr;
output [15:0] es_wdata;
input [15:0] es_rdata;
input es_ready;
// axi4 interface
input axi_rstn;
input axi_clk;
output axi_awvalid;
output [31:0] axi_awaddr;
output [ 2:0] axi_awprot;
input axi_awready;
output axi_wvalid;
output [31:0] axi_wdata;
output [ 3:0] axi_wstrb;
input axi_wready;
input axi_bvalid;
input [ 1:0] axi_bresp;
output axi_bready;
output axi_arvalid;
output [31:0] axi_araddr;
output [ 2:0] axi_arprot;
input axi_arready;
input axi_rvalid;
input [31:0] axi_rdata;
input [ 1:0] axi_rresp;
output axi_rready;
// processor interface
input es_start;
input es_stop;
input es_init;
input [15:0] es_sdata0;
input [15:0] es_sdata1;
input [15:0] es_sdata2;
input [15:0] es_sdata3;
input [15:0] es_sdata4;
input [15:0] es_qdata0;
input [15:0] es_qdata1;
input [15:0] es_qdata2;
input [15:0] es_qdata3;
input [15:0] es_qdata4;
input [ 4:0] es_prescale;
input [11:0] es_hoffset_min;
input [11:0] es_hoffset_max;
input [11:0] es_hoffset_step;
input [ 7:0] es_voffset_min;
input [ 7:0] es_voffset_max;
input [ 7:0] es_voffset_step;
input [31:0] es_start_addr;
output es_dmaerr;
output es_status;
// debug interface
output [275:0] es_dbg_data;
output [ 7:0] es_dbg_trigger;
// internal registers
reg axi_req_toggle_m1 = 'd0;
reg axi_req_toggle_m2 = 'd0;
reg axi_req_toggle_m3 = 'd0;
reg axi_awvalid = 'd0;
reg [31:0] axi_awaddr = 'd0;
reg axi_wvalid = 'd0;
reg [31:0] axi_wdata = 'd0;
reg axi_err = 'd0;
reg es_dmaerr_m1 = 'd0;
reg es_dmaerr = 'd0;
reg es_dma_req_toggle = 'd0;
reg [31:0] es_dma_addr = 'd0;
reg [31:0] es_dma_data = 'd0;
reg es_status = 'd0;
reg es_ut = 'd0;
reg [31:0] es_dma_addr_int = 'd0;
reg [11:0] es_hoffset = 'd0;
reg [ 7:0] es_voffset = 'd0;
reg [15:0] es_hoffset_rdata = 'd0;
reg [15:0] es_voffset_rdata = 'd0;
reg [15:0] es_ctrl_rdata = 'd0;
reg [15:0] es_scnt_rdata = 'd0;
reg [15:0] es_ecnt_rdata = 'd0;
reg [ 5:0] es_fsm = 'd0;
reg es_sel = 'd0;
reg es_wr = 'd0;
reg [11:0] es_addr = 'd0;
reg [15:0] es_wdata = 'd0;
// internal signals
wire axi_req_s;
wire es_heos_s;
wire es_eos_s;
wire [ 7:0] es_voffset_2_s;
wire [ 7:0] es_voffset_n_s;
wire [ 7:0] es_voffset_s;
// debug interface
assign es_dbg_trigger = {es_start, es_eos_s, es_fsm};
assign es_dbg_data[ 0: 0] = es_sel;
assign es_dbg_data[ 1: 1] = es_wr;
assign es_dbg_data[ 13: 2] = es_addr;
assign es_dbg_data[ 29: 14] = es_wdata;
assign es_dbg_data[ 45: 30] = es_rdata;
assign es_dbg_data[ 46: 46] = es_ready;
assign es_dbg_data[ 47: 47] = axi_awvalid;
assign es_dbg_data[ 79: 48] = axi_awaddr;
assign es_dbg_data[ 80: 80] = axi_awready;
assign es_dbg_data[ 81: 81] = axi_wvalid;
assign es_dbg_data[113: 82] = axi_wdata;
assign es_dbg_data[117:114] = axi_wstrb;
assign es_dbg_data[118:118] = axi_wready;
assign es_dbg_data[119:119] = axi_bvalid;
assign es_dbg_data[121:120] = axi_bresp;
assign es_dbg_data[122:122] = axi_bready;
assign es_dbg_data[123:123] = es_dmaerr;
assign es_dbg_data[124:124] = es_start;
assign es_dbg_data[125:125] = es_init;
assign es_dbg_data[126:126] = es_status;
assign es_dbg_data[127:127] = es_ut;
assign es_dbg_data[159:128] = es_dma_addr_int;
assign es_dbg_data[171:160] = es_hoffset;
assign es_dbg_data[179:172] = es_voffset;
assign es_dbg_data[195:180] = es_hoffset_rdata;
assign es_dbg_data[211:196] = es_voffset_rdata;
assign es_dbg_data[227:212] = es_ctrl_rdata;
assign es_dbg_data[243:228] = es_scnt_rdata;
assign es_dbg_data[259:244] = es_ecnt_rdata;
assign es_dbg_data[265:260] = es_fsm;
assign es_dbg_data[266:266] = es_heos_s;
assign es_dbg_data[267:267] = es_eos_s;
assign es_dbg_data[275:268] = es_voffset_s;
// axi write interface
assign axi_awprot = 3'd0;
assign axi_wstrb = 4'hf;
assign axi_bready = 1'd1;
assign axi_arvalid = 1'd0;
assign axi_araddr = 32'd0;
assign axi_arprot = 3'd0;
assign axi_rready = 1'd1;
assign axi_req_s = axi_req_toggle_m3 ^ axi_req_toggle_m2;
always @(negedge axi_rstn or posedge axi_clk) begin
if (axi_rstn == 0) begin
axi_req_toggle_m1 <= 'd0;
axi_req_toggle_m2 <= 'd0;
axi_req_toggle_m3 <= 'd0;
axi_awvalid <= 'b0;
axi_awaddr <= 'd0;
axi_wvalid <= 'b0;
axi_wdata <= 'd0;
axi_err <= 'd0;
end else begin
axi_req_toggle_m1 <= es_dma_req_toggle;
axi_req_toggle_m2 <= axi_req_toggle_m1;
axi_req_toggle_m3 <= axi_req_toggle_m2;
if ((axi_awvalid == 1'b1) && (axi_awready == 1'b1)) begin
axi_awvalid <= 1'b0;
axi_awaddr <= 32'd0;
end else if (axi_req_s == 1'b1) begin
axi_awvalid <= 1'b1;
axi_awaddr <= es_dma_addr;
end
if ((axi_wvalid == 1'b1) && (axi_wready == 1'b1)) begin
axi_wvalid <= 1'b0;
axi_wdata <= 32'd0;
end else if (axi_req_s == 1'b1) begin
axi_wvalid <= 1'b1;
axi_wdata <= es_dma_data;
end
if (axi_bvalid == 1'b1) begin
axi_err <= axi_bresp[1] | axi_bresp[0];
end
end
end
always @(posedge drp_clk) begin
if (drp_rst == 1'b1) begin
es_dmaerr_m1 <= 'd0;
es_dmaerr <= 'd0;
es_dma_req_toggle <= 'd0;
es_dma_addr <= 'd0;
es_dma_data <= 'd0;
end else begin
es_dmaerr_m1 <= axi_err;
es_dmaerr <= es_dmaerr_m1;
if (es_fsm == ES_FSM_DATA) begin
es_dma_req_toggle <= ~es_dma_req_toggle;
es_dma_addr <= es_dma_addr_int;
es_dma_data <= {es_scnt_rdata, es_ecnt_rdata};
end
end
end
// prescale, horizontal and vertical offsets
assign es_heos_s = (es_hoffset == es_hoffset_max) ? es_ut : 1'b0;
assign es_eos_s = (es_voffset == es_voffset_max) ? es_heos_s : 1'b0;
assign es_voffset_2_s = ~es_voffset + 1'b1;
assign es_voffset_n_s = {1'b1, es_voffset_2_s[6:0]};
assign es_voffset_s = (es_voffset[7] == 1'b1) ? es_voffset_n_s : es_voffset;
always @(posedge drp_clk) begin
if (es_fsm == ES_FSM_IDLE) begin
es_status <= 1'b0;
end else begin
es_status <= 1'b1;
end
if (es_fsm == ES_FSM_IDLE) begin
es_ut <= 1'b0;
es_dma_addr_int <= es_start_addr;
es_hoffset <= es_hoffset_min;
es_voffset <= es_voffset_min;
end else if (es_fsm == ES_FSM_DATA) begin
es_ut <= ~es_ut;
es_dma_addr_int <= es_dma_addr_int + 3'd4;
if (es_heos_s == 1'b1) begin
es_hoffset <= es_hoffset_min;
end else if (es_ut == 1'b1) begin
es_hoffset <= es_hoffset + es_hoffset_step;
end
if (es_heos_s == 1'b1) begin
es_voffset <= es_voffset + es_voffset_step;
end
end
end
// read-modify-write parameters (gt's are full of mixed up controls)
always @(posedge drp_clk) begin
if ((es_fsm == ES_FSM_HOFFSET_RRDY) && (es_ready == 1'b1)) begin
es_hoffset_rdata <= es_rdata;
end
if ((es_fsm == ES_FSM_VOFFSET_RRDY) && (es_ready == 1'b1)) begin
es_voffset_rdata <= es_rdata;
end
if (((es_fsm == ES_FSM_CTRLINIT_RRDY) || (es_fsm == ES_FSM_CTRLSTART_RRDY) ||
(es_fsm == ES_FSM_CTRLSTOP_RRDY)) && (es_ready == 1'b1)) begin
es_ctrl_rdata <= es_rdata;
end
if ((es_fsm == ES_FSM_SCNT_RRDY) && (es_ready == 1'b1)) begin
es_scnt_rdata <= es_rdata;
end
if ((es_fsm == ES_FSM_ECNT_RRDY) && (es_ready == 1'b1)) begin
es_ecnt_rdata <= es_rdata;
end
end
// eye scan state machine- write vertical and horizontal offsets
// and read back sample and error counters
always @(posedge drp_clk) begin
if ((drp_rst == 1'b1) || (es_stop == 1'b1)) begin
es_fsm <= ES_FSM_IDLE;
end else begin
case (es_fsm)
ES_FSM_IDLE: begin // idle
if (es_start == 1'b0) begin
es_fsm <= ES_FSM_IDLE;
end else if (es_init == 1'b1) begin
es_fsm <= ES_FSM_CTRLINIT_READ;
end else begin
es_fsm <= ES_FSM_HOFFSET_READ;
end
end
ES_FSM_CTRLINIT_READ: begin // control read
es_fsm <= ES_FSM_CTRLINIT_RRDY;
end
ES_FSM_CTRLINIT_RRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_CTRLINIT_WRITE;
end else begin
es_fsm <= ES_FSM_CTRLINIT_RRDY;
end
end
ES_FSM_CTRLINIT_WRITE: begin // control write
es_fsm <= ES_FSM_CTRLINIT_WRDY;
end
ES_FSM_CTRLINIT_WRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SDATA0_WRITE;
end else begin
es_fsm <= ES_FSM_CTRLINIT_WRDY;
end
end
ES_FSM_SDATA0_WRITE: begin // sdata write
es_fsm <= ES_FSM_SDATA0_WRDY;
end
ES_FSM_SDATA0_WRDY: begin // sdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SDATA1_WRITE;
end else begin
es_fsm <= ES_FSM_SDATA0_WRDY;
end
end
ES_FSM_SDATA1_WRITE: begin // sdata write
es_fsm <= ES_FSM_SDATA1_WRDY;
end
ES_FSM_SDATA1_WRDY: begin // sdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SDATA2_WRITE;
end else begin
es_fsm <= ES_FSM_SDATA1_WRDY;
end
end
ES_FSM_SDATA2_WRITE: begin // sdata write
es_fsm <= ES_FSM_SDATA2_WRDY;
end
ES_FSM_SDATA2_WRDY: begin // sdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SDATA3_WRITE;
end else begin
es_fsm <= ES_FSM_SDATA2_WRDY;
end
end
ES_FSM_SDATA3_WRITE: begin // sdata write
es_fsm <= ES_FSM_SDATA3_WRDY;
end
ES_FSM_SDATA3_WRDY: begin // sdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SDATA4_WRITE;
end else begin
es_fsm <= ES_FSM_SDATA3_WRDY;
end
end
ES_FSM_SDATA4_WRITE: begin // sdata write
es_fsm <= ES_FSM_SDATA4_WRDY;
end
ES_FSM_SDATA4_WRDY: begin // sdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_QDATA0_WRITE;
end else begin
es_fsm <= ES_FSM_SDATA4_WRDY;
end
end
ES_FSM_QDATA0_WRITE: begin // qdata write
es_fsm <= ES_FSM_QDATA0_WRDY;
end
ES_FSM_QDATA0_WRDY: begin // qdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_QDATA1_WRITE;
end else begin
es_fsm <= ES_FSM_QDATA0_WRDY;
end
end
ES_FSM_QDATA1_WRITE: begin // qdata write
es_fsm <= ES_FSM_QDATA1_WRDY;
end
ES_FSM_QDATA1_WRDY: begin // qdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_QDATA2_WRITE;
end else begin
es_fsm <= ES_FSM_QDATA1_WRDY;
end
end
ES_FSM_QDATA2_WRITE: begin // qdata write
es_fsm <= ES_FSM_QDATA2_WRDY;
end
ES_FSM_QDATA2_WRDY: begin // qdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_QDATA3_WRITE;
end else begin
es_fsm <= ES_FSM_QDATA2_WRDY;
end
end
ES_FSM_QDATA3_WRITE: begin // qdata write
es_fsm <= ES_FSM_QDATA3_WRDY;
end
ES_FSM_QDATA3_WRDY: begin // qdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_QDATA4_WRITE;
end else begin
es_fsm <= ES_FSM_QDATA3_WRDY;
end
end
ES_FSM_QDATA4_WRITE: begin // qdata write
es_fsm <= ES_FSM_QDATA4_WRDY;
end
ES_FSM_QDATA4_WRDY: begin // qdata ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_HOFFSET_READ;
end else begin
es_fsm <= ES_FSM_QDATA4_WRDY;
end
end
ES_FSM_HOFFSET_READ: begin // horizontal offset read
es_fsm <= ES_FSM_HOFFSET_RRDY;
end
ES_FSM_HOFFSET_RRDY: begin // horizontal offset ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_HOFFSET_WRITE;
end else begin
es_fsm <= ES_FSM_HOFFSET_RRDY;
end
end
ES_FSM_HOFFSET_WRITE: begin // horizontal offset write
es_fsm <= ES_FSM_HOFFSET_WRDY;
end
ES_FSM_HOFFSET_WRDY: begin // horizontal offset ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_VOFFSET_READ;
end else begin
es_fsm <= ES_FSM_HOFFSET_WRDY;
end
end
ES_FSM_VOFFSET_READ: begin // vertical offset read
es_fsm <= ES_FSM_VOFFSET_RRDY;
end
ES_FSM_VOFFSET_RRDY: begin // vertical offset ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_VOFFSET_WRITE;
end else begin
es_fsm <= ES_FSM_VOFFSET_RRDY;
end
end
ES_FSM_VOFFSET_WRITE: begin // vertical offset write
es_fsm <= ES_FSM_VOFFSET_WRDY;
end
ES_FSM_VOFFSET_WRDY: begin // vertical offset ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_CTRLSTART_READ;
end else begin
es_fsm <= ES_FSM_VOFFSET_WRDY;
end
end
ES_FSM_CTRLSTART_READ: begin // control read
es_fsm <= ES_FSM_CTRLSTART_RRDY;
end
ES_FSM_CTRLSTART_RRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_CTRLSTART_WRITE;
end else begin
es_fsm <= ES_FSM_CTRLSTART_RRDY;
end
end
ES_FSM_CTRLSTART_WRITE: begin // control write
es_fsm <= ES_FSM_CTRLSTART_WRDY;
end
ES_FSM_CTRLSTART_WRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_STATUS_READ;
end else begin
es_fsm <= ES_FSM_CTRLSTART_WRDY;
end
end
ES_FSM_STATUS_READ: begin // status read
es_fsm <= ES_FSM_STATUS_RRDY;
end
ES_FSM_STATUS_RRDY: begin // status ready
if (es_ready == 1'b0) begin
es_fsm <= ES_FSM_STATUS_RRDY;
end else if (es_rdata[3:0] == 4'b0101) begin
es_fsm <= ES_FSM_CTRLSTOP_READ;
end else begin
es_fsm <= ES_FSM_STATUS_READ;
end
end
ES_FSM_CTRLSTOP_READ: begin // control read
es_fsm <= ES_FSM_CTRLSTOP_RRDY;
end
ES_FSM_CTRLSTOP_RRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_CTRLSTOP_WRITE;
end else begin
es_fsm <= ES_FSM_CTRLSTOP_RRDY;
end
end
ES_FSM_CTRLSTOP_WRITE: begin // control write
es_fsm <= ES_FSM_CTRLSTOP_WRDY;
end
ES_FSM_CTRLSTOP_WRDY: begin // control ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_SCNT_READ;
end else begin
es_fsm <= ES_FSM_CTRLSTOP_WRDY;
end
end
ES_FSM_SCNT_READ: begin // read sample count
es_fsm <= ES_FSM_SCNT_RRDY;
end
ES_FSM_SCNT_RRDY: begin // sample count ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_ECNT_READ;
end else begin
es_fsm <= ES_FSM_SCNT_RRDY;
end
end
ES_FSM_ECNT_READ: begin // read error count
es_fsm <= ES_FSM_ECNT_RRDY;
end
ES_FSM_ECNT_RRDY: begin // error count ready
if (es_ready == 1'b1) begin
es_fsm <= ES_FSM_DATA;
end else begin
es_fsm <= ES_FSM_ECNT_RRDY;
end
end
ES_FSM_DATA: begin // data phase
if (es_eos_s == 1'b1) begin
es_fsm <= ES_FSM_IDLE;
end else if (es_ut == 1'b1) begin
es_fsm <= ES_FSM_HOFFSET_READ;
end else begin
es_fsm <= ES_FSM_VOFFSET_READ;
end
end
default: begin
es_fsm <= ES_FSM_IDLE;
end
endcase
end
end
// drp signals controlled by the fsm
always @(posedge drp_clk) begin
case (es_fsm)
ES_FSM_CTRLINIT_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_CTRLINIT_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= {es_ctrl_rdata[15:10], 2'b11, es_ctrl_rdata[7:0]};
end
ES_FSM_SDATA0_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_SDATA0_ADDR;
es_wdata <= es_sdata0;
end
ES_FSM_SDATA1_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_SDATA1_ADDR;
es_wdata <= es_sdata1;
end
ES_FSM_SDATA2_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_SDATA2_ADDR;
es_wdata <= es_sdata2;
end
ES_FSM_SDATA3_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_SDATA3_ADDR;
es_wdata <= es_sdata3;
end
ES_FSM_SDATA4_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_SDATA4_ADDR;
es_wdata <= es_sdata4;
end
ES_FSM_QDATA0_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_QDATA0_ADDR;
es_wdata <= es_qdata0;
end
ES_FSM_QDATA1_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_QDATA1_ADDR;
es_wdata <= es_qdata1;
end
ES_FSM_QDATA2_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_QDATA2_ADDR;
es_wdata <= es_qdata2;
end
ES_FSM_QDATA3_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_QDATA3_ADDR;
es_wdata <= es_qdata3;
end
ES_FSM_QDATA4_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_QDATA4_ADDR;
es_wdata <= es_qdata4;
end
ES_FSM_HOFFSET_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_HOFFSET_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_HOFFSET_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_HOFFSET_ADDR;
es_wdata <= {es_hoffset_rdata[15:12], es_hoffset};
end
ES_FSM_VOFFSET_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_VOFFSET_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_VOFFSET_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_VOFFSET_ADDR;
es_wdata <= {es_prescale, es_voffset_rdata[10:9], es_ut, es_voffset_s};
end
ES_FSM_CTRLSTART_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_CTRLSTART_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= {es_ctrl_rdata[15:6], 6'd1};
end
ES_FSM_STATUS_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_STATUS_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_CTRLSTOP_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_CTRLSTOP_WRITE: begin
es_sel <= 1'b1;
es_wr <= 1'b1;
es_addr <= ES_DRP_CTRL_ADDR;
es_wdata <= {es_ctrl_rdata[15:6], 6'd0};
end
ES_FSM_SCNT_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_SCNT_ADDR;
es_wdata <= 16'h0000;
end
ES_FSM_ECNT_READ: begin
es_sel <= 1'b1;
es_wr <= 1'b0;
es_addr <= ES_DRP_ECNT_ADDR;
es_wdata <= 16'h0000;
end
default: begin
es_sel <= 1'b0;
es_wr <= 1'b0;
es_addr <= 9'h000;
es_wdata <= 16'h0000;
end
endcase
end
endmodule
// ***************************************************************************
// ***************************************************************************

186
library/common/ad_iqcor.v Normal file
View File

@ -0,0 +1,186 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// iq correction = a*(i+x) + b*(q+y); offsets are added in dcfilter.
module ad_iqcor (
// data interface
clk,
valid,
data_i,
data_q,
valid_out,
data_out,
// control interface
iqcor_enable,
iqcor_coeff_1,
iqcor_coeff_2);
// select i/q if disabled
parameter IQSEL = 0;
// data interface
input clk;
input valid;
input [15:0] data_i;
input [15:0] data_q;
output valid_out;
output [15:0] data_out;
// control interface
input iqcor_enable;
input [15:0] iqcor_coeff_1;
input [15:0] iqcor_coeff_2;
// internal registers
reg p1_valid = 'd0;
reg [15:0] p1_data_i = 'd0;
reg [15:0] p1_data_q = 'd0;
reg p2_valid = 'd0;
reg p2_sign_i = 'd0;
reg p2_sign_q = 'd0;
reg [14:0] p2_magn_i = 'd0;
reg [14:0] p2_magn_q = 'd0;
reg p3_valid = 'd0;
reg [15:0] p3_data_i = 'd0;
reg [15:0] p3_data_q = 'd0;
reg p4_valid = 'd0;
reg [15:0] p4_data = 'd0;
reg valid_out = 'd0;
reg [15:0] data_out = 'd0;
// internal signals
wire [15:0] p2_data_i_s;
wire [15:0] p2_data_q_s;
wire p3_valid_s;
wire [31:0] p3_magn_i_s;
wire p3_sign_i_s;
wire [31:0] p3_magn_q_s;
wire p3_sign_q_s;
wire [15:0] p3_data_2s_i_p_s;
wire [15:0] p3_data_2s_q_p_s;
wire [15:0] p3_data_2s_i_n_s;
wire [15:0] p3_data_2s_q_n_s;
// apply offsets first
always @(posedge clk) begin
p1_valid <= valid;
p1_data_i <= data_i;
p1_data_q <= data_q;
end
// convert to sign-magnitude
assign p2_data_i_s = ~p1_data_i + 1'b1;
assign p2_data_q_s = ~p1_data_q + 1'b1;
always @(posedge clk) begin
p2_valid <= p1_valid;
p2_sign_i <= p1_data_i[15] ^ iqcor_coeff_1[15];
p2_sign_q <= p1_data_q[15] ^ iqcor_coeff_2[15];
p2_magn_i <= (p1_data_i[15] == 1'b1) ? p2_data_i_s[14:0] : p1_data_i[14:0];
p2_magn_q <= (p1_data_q[15] == 1'b1) ? p2_data_q_s[14:0] : p1_data_q[14:0];
end
// scaling functions - i
ad_mul_u16 #(.DELAY_DATA_WIDTH(2)) i_mul_u16_i (
.clk (clk),
.data_a ({1'b0, p2_magn_i}),
.data_b ({1'b0, iqcor_coeff_1[14:0]}),
.data_p (p3_magn_i_s),
.ddata_in ({p2_valid, p2_sign_i}),
.ddata_out ({p3_valid_s, p3_sign_i_s}));
// scaling functions - q
ad_mul_u16 #(.DELAY_DATA_WIDTH(1)) i_mul_u16_q (
.clk (clk),
.data_a ({1'b0, p2_magn_q}),
.data_b ({1'b0, iqcor_coeff_2[14:0]}),
.data_p (p3_magn_q_s),
.ddata_in (p2_sign_q),
.ddata_out (p3_sign_q_s));
// convert to 2s-complements
assign p3_data_2s_i_p_s = {1'b0, p3_magn_i_s[28:14]};
assign p3_data_2s_q_p_s = {1'b0, p3_magn_q_s[28:14]};
assign p3_data_2s_i_n_s = ~p3_data_2s_i_p_s + 1'b1;
assign p3_data_2s_q_n_s = ~p3_data_2s_q_p_s + 1'b1;
always @(posedge clk) begin
p3_valid <= p3_valid_s;
p3_data_i <= (p3_sign_i_s == 1'b1) ? p3_data_2s_i_n_s : p3_data_2s_i_p_s;
p3_data_q <= (p3_sign_q_s == 1'b1) ? p3_data_2s_q_n_s : p3_data_2s_q_p_s;
end
// corrected output is sum of two
always @(posedge clk) begin
p4_valid <= p3_valid;
p4_data <= p3_data_i + p3_data_q;
end
// output registers
always @(posedge clk) begin
if (iqcor_enable == 1'b1) begin
valid_out <= p4_valid;
data_out <= p4_data;
end else if (IQSEL == 1) begin
valid_out <= valid;
data_out <= data_q;
end else begin
valid_out <= valid;
data_out <= data_i;
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,84 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_jesd_align (
// jesd interface
rx_clk,
rx_sof,
rx_ip_data,
rx_data);
// jesd interface
input rx_clk;
input [ 3:0] rx_sof;
input [31:0] rx_ip_data;
// aligned data
output [31:0] rx_data;
// internal registers
reg [31:0] rx_ip_data_d = 'd0;
reg [31:0] rx_data = 'd0;
// dword may contain more than one frame per clock
always @(posedge rx_clk) begin
rx_ip_data_d <= rx_ip_data;
if (rx_sof[0] == 1'b1) begin
rx_data <= rx_ip_data;
end else if (rx_sof[1] == 1'b1) begin
rx_data <= {rx_ip_data[ 7:0], rx_ip_data_d[31: 8]};
end else if (rx_sof[2] == 1'b1) begin
rx_data <= {rx_ip_data[15:0], rx_ip_data_d[31:16]};
end else if (rx_sof[3] == 1'b1) begin
rx_data <= {rx_ip_data[23:0], rx_ip_data_d[31:24]};
end else begin
rx_data <= 32'd0;
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

83
library/common/ad_mem.v Normal file
View File

@ -0,0 +1,83 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_mem (
clka,
wea,
addra,
dina,
clkb,
addrb,
doutb);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 5;
localparam DW = DATA_WIDTH - 1;
localparam AW = ADDR_WIDTH - 1;
input clka;
input wea;
input [AW:0] addra;
input [DW:0] dina;
input clkb;
input [AW:0] addrb;
output [DW:0] doutb;
reg [DW:0] m_ram[0:((2**ADDR_WIDTH)-1)];
reg [DW:0] doutb;
always @(posedge clka) begin
if (wea == 1'b1) begin
m_ram[addra] <= dina;
end
end
always @(posedge clkb) begin
doutb <= m_ram[addrb];
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,250 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// MMCM with DRP and device specific
`timescale 1ns/100ps
module ad_mmcm_drp (
// clocks
clk,
mmcm_rst,
mmcm_clk_0,
mmcm_clk_1,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked);
// parameters
parameter MMCM_DEVICE_TYPE = 0;
localparam MMCM_DEVICE_7SERIES = 0;
localparam MMCM_DEVICE_VIRTEX6 = 1;
parameter MMCM_CLKIN_PERIOD = 1.667;
parameter MMCM_VCO_DIV = 6;
parameter MMCM_VCO_MUL = 12.000;
parameter MMCM_CLK0_DIV = 2.000;
parameter MMCM_CLK1_DIV = 6;
// clocks
input clk;
input mmcm_rst;
output mmcm_clk_0;
output mmcm_clk_1;
// drp interface
input drp_clk;
input drp_rst;
input drp_sel;
input drp_wr;
input [11:0] drp_addr;
input [15:0] drp_wdata;
output [15:0] drp_rdata;
output drp_ready;
output drp_locked;
// internal registers
reg [15:0] drp_rdata = 'd0;
reg drp_ready = 'd0;
reg drp_locked_m1 = 'd0;
reg drp_locked = 'd0;
// internal signals
wire bufg_fb_clk_s;
wire mmcm_fb_clk_s;
wire mmcm_clk_0_s;
wire mmcm_clk_1_s;
wire mmcm_locked_s;
wire [15:0] drp_rdata_s;
wire drp_ready_s;
// drp read and locked
always @(posedge drp_clk) begin
drp_rdata <= drp_rdata_s;
drp_ready <= drp_ready_s;
if (drp_rst == 1'b1) begin
drp_locked_m1 <= 1'd0;
drp_locked <= 1'd0;
end else begin
drp_locked_m1 <= mmcm_locked_s;
drp_locked <= drp_locked_m1;
end
end
// instantiations
generate
if (MMCM_DEVICE_TYPE == MMCM_DEVICE_VIRTEX6) begin
MMCM_ADV #(
.BANDWIDTH ("OPTIMIZED"),
.CLKOUT4_CASCADE ("FALSE"),
.CLOCK_HOLD ("FALSE"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (MMCM_VCO_DIV),
.CLKFBOUT_MULT_F (MMCM_VCO_MUL),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_USE_FINE_PS ("FALSE"),
.CLKOUT1_DIVIDE (MMCM_CLK1_DIV),
.CLKOUT1_PHASE (0.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_USE_FINE_PS ("FALSE"),
.CLKIN1_PERIOD (MMCM_CLKIN_PERIOD),
.REF_JITTER1 (0.010))
i_mmcm (
.CLKIN1 (clk),
.CLKFBIN (bufg_fb_clk_s),
.CLKFBOUT (mmcm_fb_clk_s),
.CLKOUT0 (mmcm_clk_0_s),
.CLKOUT1 (mmcm_clk_1_s),
.LOCKED (mmcm_locked_s),
.DCLK (drp_clk),
.DEN (drp_sel),
.DADDR (drp_addr[6:0]),
.DWE (drp_wr),
.DI (drp_wdata),
.DO (drp_rdata_s),
.DRDY (drp_ready_s),
.CLKFBOUTB (),
.CLKOUT0B (),
.CLKOUT1B (),
.CLKOUT2 (),
.CLKOUT2B (),
.CLKOUT3 (),
.CLKOUT3B (),
.CLKOUT4 (),
.CLKOUT5 (),
.CLKOUT6 (),
.CLKIN2 (1'b0),
.CLKINSEL (1'b1),
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE (),
.CLKINSTOPPED (),
.CLKFBSTOPPED (),
.PWRDWN (1'b0),
.RST (mmcm_rst));
end
if (MMCM_DEVICE_TYPE == MMCM_DEVICE_7SERIES) begin
MMCME2_ADV #(
.BANDWIDTH ("OPTIMIZED"),
.CLKOUT4_CASCADE ("FALSE"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (MMCM_VCO_DIV),
.CLKFBOUT_MULT_F (MMCM_VCO_MUL),
.CLKFBOUT_PHASE (0.000),
.CLKFBOUT_USE_FINE_PS ("FALSE"),
.CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_USE_FINE_PS ("FALSE"),
.CLKOUT1_DIVIDE (MMCM_CLK1_DIV),
.CLKOUT1_PHASE (0.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_USE_FINE_PS ("FALSE"),
.CLKIN1_PERIOD (MMCM_CLKIN_PERIOD),
.REF_JITTER1 (0.010))
i_mmcm (
.CLKIN1 (clk),
.CLKFBIN (bufg_fb_clk_s),
.CLKFBOUT (mmcm_fb_clk_s),
.CLKOUT0 (mmcm_clk_0_s),
.CLKOUT1 (mmcm_clk_1_s),
.LOCKED (mmcm_locked_s),
.DCLK (drp_clk),
.DEN (drp_sel),
.DADDR (drp_addr[6:0]),
.DWE (drp_wr),
.DI (drp_wdata),
.DO (drp_rdata_s),
.DRDY (drp_ready_s),
.CLKFBOUTB (),
.CLKOUT0B (),
.CLKOUT1B (),
.CLKOUT2 (),
.CLKOUT2B (),
.CLKOUT3 (),
.CLKOUT3B (),
.CLKOUT4 (),
.CLKOUT5 (),
.CLKOUT6 (),
.CLKIN2 (1'b0),
.CLKINSEL (1'b1),
.PSCLK (1'b0),
.PSEN (1'b0),
.PSINCDEC (1'b0),
.PSDONE (),
.CLKINSTOPPED (),
.CLKFBSTOPPED (),
.PWRDWN (1'b0),
.RST (mmcm_rst));
end
endgenerate
BUFG i_fb_clk_bufg (.I (mmcm_fb_clk_s), .O (bufg_fb_clk_s));
BUFG i_clk_0_bufg (.I (mmcm_clk_0_s), .O (mmcm_clk_0));
BUFG i_clk_1_bufg (.I (mmcm_clk_1_s), .O (mmcm_clk_1));
endmodule
// ***************************************************************************
// ***************************************************************************

250
library/common/ad_mul_u16.v Normal file
View File

@ -0,0 +1,250 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// both inputs are considered unsigned 16 bits-
// ddata is delay matched generic data
`timescale 1ps/1ps
module ad_mul_u16 (
// data_p = data_a * data_b;
clk,
data_a,
data_b,
data_p,
// delay interface
ddata_in,
ddata_out);
// delayed data bus width
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// data_p = data_a * data_b;
input clk;
input [15:0] data_a;
input [15:0] data_b;
output [31:0] data_p;
// delay interface
input [DW:0] ddata_in;
output [DW:0] ddata_out;
// internal registers
reg [DW:0] ddata_in_d = 'd0;
reg [16:0] data_a_p = 'd0;
reg [16:0] data_a_n = 'd0;
reg [15:0] data_b_d = 'd0;
reg [DW:0] p1_ddata = 'd0;
reg [31:0] p1_data_p_0 = 'd0;
reg [31:0] p1_data_p_1 = 'd0;
reg [31:0] p1_data_p_2 = 'd0;
reg [31:0] p1_data_p_3 = 'd0;
reg [31:0] p1_data_p_4 = 'd0;
reg [31:0] p1_data_p_5 = 'd0;
reg [31:0] p1_data_p_6 = 'd0;
reg [31:0] p1_data_p_7 = 'd0;
reg [31:0] p1_data_p_8 = 'd0;
reg [DW:0] p2_ddata = 'd0;
reg [31:0] p2_data_p_0 = 'd0;
reg [31:0] p2_data_p_1 = 'd0;
reg [31:0] p2_data_p_2 = 'd0;
reg [31:0] p2_data_p_3 = 'd0;
reg [31:0] p2_data_p_4 = 'd0;
reg [DW:0] p3_ddata = 'd0;
reg [31:0] p3_data_p_0 = 'd0;
reg [31:0] p3_data_p_1 = 'd0;
reg [31:0] p3_data_p_2 = 'd0;
reg [DW:0] p4_ddata = 'd0;
reg [31:0] p4_data_p_0 = 'd0;
reg [31:0] p4_data_p_1 = 'd0;
reg [DW:0] ddata_out = 'd0;
reg [31:0] data_p = 'd0;
// internal signals
wire [16:0] data_a_p_17_s;
wire [16:0] data_a_n_17_s;
wire [31:0] p1_data_a_1p_s;
wire [31:0] p1_data_a_1n_s;
wire [31:0] p1_data_a_2p_s;
wire [31:0] p1_data_a_2n_s;
// pipe line stage 0, get the two's complement versions
assign data_a_p_17_s = {1'b0, data_a};
assign data_a_n_17_s = ~data_a_p_17_s + 1'b1;
always @(posedge clk) begin
ddata_in_d <= ddata_in;
data_a_p <= data_a_p_17_s;
data_a_n <= data_a_n_17_s;
data_b_d <= data_b;
end
// pipe line stage 1, get the partial products
assign p1_data_a_1p_s = {{15{data_a_p[16]}}, data_a_p};
assign p1_data_a_1n_s = {{15{data_a_n[16]}}, data_a_n};
assign p1_data_a_2p_s = {{14{data_a_p[16]}}, data_a_p, 1'b0};
assign p1_data_a_2n_s = {{14{data_a_n[16]}}, data_a_n, 1'b0};
always @(posedge clk) begin
p1_ddata <= ddata_in_d;
case (data_b_d[1:0])
2'b11: p1_data_p_0 <= p1_data_a_1n_s;
2'b10: p1_data_p_0 <= p1_data_a_2n_s;
2'b01: p1_data_p_0 <= p1_data_a_1p_s;
default: p1_data_p_0 <= 32'd0;
endcase
case (data_b_d[3:1])
3'b011: p1_data_p_1 <= {p1_data_a_2p_s[29:0], 2'd0};
3'b100: p1_data_p_1 <= {p1_data_a_2n_s[29:0], 2'd0};
3'b001: p1_data_p_1 <= {p1_data_a_1p_s[29:0], 2'd0};
3'b010: p1_data_p_1 <= {p1_data_a_1p_s[29:0], 2'd0};
3'b101: p1_data_p_1 <= {p1_data_a_1n_s[29:0], 2'd0};
3'b110: p1_data_p_1 <= {p1_data_a_1n_s[29:0], 2'd0};
default: p1_data_p_1 <= 32'd0;
endcase
case (data_b_d[5:3])
3'b011: p1_data_p_2 <= {p1_data_a_2p_s[27:0], 4'd0};
3'b100: p1_data_p_2 <= {p1_data_a_2n_s[27:0], 4'd0};
3'b001: p1_data_p_2 <= {p1_data_a_1p_s[27:0], 4'd0};
3'b010: p1_data_p_2 <= {p1_data_a_1p_s[27:0], 4'd0};
3'b101: p1_data_p_2 <= {p1_data_a_1n_s[27:0], 4'd0};
3'b110: p1_data_p_2 <= {p1_data_a_1n_s[27:0], 4'd0};
default: p1_data_p_2 <= 32'd0;
endcase
case (data_b_d[7:5])
3'b011: p1_data_p_3 <= {p1_data_a_2p_s[25:0], 6'd0};
3'b100: p1_data_p_3 <= {p1_data_a_2n_s[25:0], 6'd0};
3'b001: p1_data_p_3 <= {p1_data_a_1p_s[25:0], 6'd0};
3'b010: p1_data_p_3 <= {p1_data_a_1p_s[25:0], 6'd0};
3'b101: p1_data_p_3 <= {p1_data_a_1n_s[25:0], 6'd0};
3'b110: p1_data_p_3 <= {p1_data_a_1n_s[25:0], 6'd0};
default: p1_data_p_3 <= 32'd0;
endcase
case (data_b_d[9:7])
3'b011: p1_data_p_4 <= {p1_data_a_2p_s[23:0], 8'd0};
3'b100: p1_data_p_4 <= {p1_data_a_2n_s[23:0], 8'd0};
3'b001: p1_data_p_4 <= {p1_data_a_1p_s[23:0], 8'd0};
3'b010: p1_data_p_4 <= {p1_data_a_1p_s[23:0], 8'd0};
3'b101: p1_data_p_4 <= {p1_data_a_1n_s[23:0], 8'd0};
3'b110: p1_data_p_4 <= {p1_data_a_1n_s[23:0], 8'd0};
default: p1_data_p_4 <= 32'd0;
endcase
case (data_b_d[11:9])
3'b011: p1_data_p_5 <= {p1_data_a_2p_s[21:0], 10'd0};
3'b100: p1_data_p_5 <= {p1_data_a_2n_s[21:0], 10'd0};
3'b001: p1_data_p_5 <= {p1_data_a_1p_s[21:0], 10'd0};
3'b010: p1_data_p_5 <= {p1_data_a_1p_s[21:0], 10'd0};
3'b101: p1_data_p_5 <= {p1_data_a_1n_s[21:0], 10'd0};
3'b110: p1_data_p_5 <= {p1_data_a_1n_s[21:0], 10'd0};
default: p1_data_p_5 <= 32'd0;
endcase
case (data_b_d[13:11])
3'b011: p1_data_p_6 <= {p1_data_a_2p_s[19:0], 12'd0};
3'b100: p1_data_p_6 <= {p1_data_a_2n_s[19:0], 12'd0};
3'b001: p1_data_p_6 <= {p1_data_a_1p_s[19:0], 12'd0};
3'b010: p1_data_p_6 <= {p1_data_a_1p_s[19:0], 12'd0};
3'b101: p1_data_p_6 <= {p1_data_a_1n_s[19:0], 12'd0};
3'b110: p1_data_p_6 <= {p1_data_a_1n_s[19:0], 12'd0};
default: p1_data_p_6 <= 32'd0;
endcase
case (data_b_d[15:13])
3'b011: p1_data_p_7 <= {p1_data_a_2p_s[17:0], 14'd0};
3'b100: p1_data_p_7 <= {p1_data_a_2n_s[17:0], 14'd0};
3'b001: p1_data_p_7 <= {p1_data_a_1p_s[17:0], 14'd0};
3'b010: p1_data_p_7 <= {p1_data_a_1p_s[17:0], 14'd0};
3'b101: p1_data_p_7 <= {p1_data_a_1n_s[17:0], 14'd0};
3'b110: p1_data_p_7 <= {p1_data_a_1n_s[17:0], 14'd0};
default: p1_data_p_7 <= 32'd0;
endcase
case (data_b_d[15])
1'b1: p1_data_p_8 <= {p1_data_a_1p_s[15:0], 16'd0};
default: p1_data_p_8 <= 32'd0;
endcase
end
// pipe line stage 2, sum (intermediate 9 -> 5)
always @(posedge clk) begin
p2_ddata <= p1_ddata;
p2_data_p_0 <= p1_data_p_0 + p1_data_p_1;
p2_data_p_1 <= p1_data_p_2 + p1_data_p_3;
p2_data_p_2 <= p1_data_p_4 + p1_data_p_5;
p2_data_p_3 <= p1_data_p_6 + p1_data_p_7;
p2_data_p_4 <= p1_data_p_8;
end
// pipe line stage 3, sum (intermediate 5 -> 3)
always @(posedge clk) begin
p3_ddata <= p2_ddata;
p3_data_p_0 <= p2_data_p_0 + p2_data_p_4;
p3_data_p_1 <= p2_data_p_1 + p2_data_p_2;
p3_data_p_2 <= p2_data_p_3;
end
// pipe line stage 4, sum (intermediate 3 -> 2)
always @(posedge clk) begin
p4_ddata <= p3_ddata;
p4_data_p_0 <= p3_data_p_0 + p3_data_p_2;
p4_data_p_1 <= p3_data_p_1;
end
// piple line stage 5, output registers
always @(posedge clk) begin
ddata_out <= p4_ddata;
data_p <= p4_data_p_0 + p4_data_p_1;
end
endmodule
// ***************************************************************************
// ***************************************************************************

68
library/common/ad_rst.v Normal file
View File

@ -0,0 +1,68 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module ad_rst (
// clock reset
preset,
clk,
rst);
// clock reset
input preset;
input clk;
output rst;
// simple reset gen
FDPE #(.INIT(1'b1)) i_rst_reg (
.CE (1'b1),
.D (1'b0),
.PRE (preset),
.C (clk),
.Q (rst));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,161 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// serial data output interface: serdes(x8) or oddr(x2) output module
`timescale 1ps/1ps
module ad_serdes_clk (
// clock and divided clock
mmcm_rst,
clk_in_p,
clk_in_n,
clk,
div_clk,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked);
// parameters
parameter SERDES = 1;
parameter MMCM = 1;
parameter MMCM_DEVICE_TYPE = 0;
parameter MMCM_CLKIN_PERIOD = 1.667;
parameter MMCM_VCO_DIV = 6;
parameter MMCM_VCO_MUL = 12.000;
parameter MMCM_CLK0_DIV = 2.000;
parameter MMCM_CLK1_DIV = 6;
// clock and divided clock
input mmcm_rst;
input clk_in_p;
input clk_in_n;
output clk;
output div_clk;
// drp interface
input drp_clk;
input drp_rst;
input drp_sel;
input drp_wr;
input [11:0] drp_addr;
input [15:0] drp_wdata;
output [15:0] drp_rdata;
output drp_ready;
output drp_locked;
// internal signals
wire clk_in_s;
// instantiations
IBUFGDS i_clk_in_ibuf (
.I (clk_in_p),
.IB (clk_in_n),
.O (clk_in_s));
generate
if (MMCM == 1) begin
ad_mmcm_drp #(
.MMCM_DEVICE_TYPE (MMCM_DEVICE_TYPE),
.MMCM_CLKIN_PERIOD (MMCM_CLKIN_PERIOD),
.MMCM_VCO_DIV (MMCM_VCO_DIV),
.MMCM_VCO_MUL (MMCM_VCO_MUL),
.MMCM_CLK0_DIV (MMCM_CLK0_DIV),
.MMCM_CLK1_DIV (MMCM_CLK1_DIV))
i_mmcm_drp (
.clk (clk_in_s),
.mmcm_rst (mmcm_rst),
.mmcm_clk_0 (clk),
.mmcm_clk_1 (div_clk),
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel),
.drp_wr (drp_wr),
.drp_addr (drp_addr),
.drp_wdata (drp_wdata),
.drp_rdata (drp_rdata),
.drp_ready (drp_ready),
.drp_locked (drp_locked));
end
if ((MMCM == 0) && (SERDES == 0)) begin
BUFR #(.BUFR_DIVIDE("BYPASS")) i_clk_buf (
.CLR (1'b0),
.CE (1'b1),
.I (clk_in_s),
.O (clk));
assign div_clk = clk;
end
if ((MMCM == 0) && (SERDES == 1)) begin
BUFIO i_clk_buf (
.I (clk_in_s),
.O (clk));
BUFR #(.BUFR_DIVIDE("4")) i_div_clk_buf (
.CLR (1'b0),
.CE (1'b1),
.I (clk_in_s),
.O (div_clk));
end
endgenerate
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,246 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// serial data output interface: serdes(x8) or oddr(x2) output module
`timescale 1ps/1ps
module ad_serdes_out (
// reset and clocks
rst,
clk,
div_clk,
// data interface
data_s0,
data_s1,
data_s2,
data_s3,
data_s4,
data_s5,
data_s6,
data_s7,
data_out_p,
data_out_n);
// parameters
parameter DEVICE_TYPE = 0;
parameter SERDES = 1;
parameter DATA_WIDTH = 16;
localparam DEVICE_6SERIES = 1;
localparam DEVICE_7SERIES = 0;
localparam DW = DATA_WIDTH - 1;
// reset and clocks
input rst;
input clk;
input div_clk;
// data interface
input [DW:0] data_s0;
input [DW:0] data_s1;
input [DW:0] data_s2;
input [DW:0] data_s3;
input [DW:0] data_s4;
input [DW:0] data_s5;
input [DW:0] data_s6;
input [DW:0] data_s7;
output [DW:0] data_out_p;
output [DW:0] data_out_n;
// internal signals
wire [DW:0] data_out_s;
wire [DW:0] serdes_shift1_s;
wire [DW:0] serdes_shift2_s;
// instantiations
genvar l_inst;
generate
for (l_inst = 0; l_inst <= DW; l_inst = l_inst + 1) begin: g_data
if (SERDES == 0) begin
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
i_oddr (
.S (1'b0),
.CE (1'b1),
.R (rst),
.C (clk),
.D1 (data_s0[l_inst]),
.D2 (data_s1[l_inst]),
.Q (data_out_s[l_inst]));
end
if ((SERDES == 1) && (DEVICE_TYPE == DEVICE_7SERIES)) begin
OSERDESE2 #(
.DATA_RATE_OQ ("DDR"),
.DATA_RATE_TQ ("SDR"),
.DATA_WIDTH (8),
.TRISTATE_WIDTH (1),
.SERDES_MODE ("MASTER"))
i_serdes (
.D1 (data_s0[l_inst]),
.D2 (data_s1[l_inst]),
.D3 (data_s2[l_inst]),
.D4 (data_s3[l_inst]),
.D5 (data_s4[l_inst]),
.D6 (data_s5[l_inst]),
.D7 (data_s6[l_inst]),
.D8 (data_s7[l_inst]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.OCE (1'b1),
.CLK (clk),
.CLKDIV (div_clk),
.OQ (data_out_s[l_inst]),
.TQ (),
.OFB (),
.TFB (),
.TBYTEIN (1'b0),
.TBYTEOUT (),
.TCE (1'b0),
.RST (rst));
end
if ((SERDES == 1) && (DEVICE_TYPE == DEVICE_6SERIES)) begin
OSERDESE1 #(
.DATA_RATE_OQ ("DDR"),
.DATA_RATE_TQ ("SDR"),
.DATA_WIDTH (8),
.INTERFACE_TYPE ("DEFAULT"),
.TRISTATE_WIDTH (1),
.SERDES_MODE ("MASTER"))
i_serdes_m (
.D1 (data_s0[l_inst]),
.D2 (data_s1[l_inst]),
.D3 (data_s2[l_inst]),
.D4 (data_s3[l_inst]),
.D5 (data_s4[l_inst]),
.D6 (data_s5[l_inst]),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (serdes_shift1_s[l_inst]),
.SHIFTIN2 (serdes_shift2_s[l_inst]),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.OCE (1'b1),
.CLK (clk),
.CLKDIV (div_clk),
.CLKPERF (1'b0),
.CLKPERFDELAY (1'b0),
.WC (1'b0),
.ODV (1'b0),
.OQ (data_out_s[l_inst]),
.TQ (),
.OCBEXTEND (),
.OFB (),
.TFB (),
.TCE (1'b0),
.RST (rst));
OSERDESE1 #(
.DATA_RATE_OQ ("DDR"),
.DATA_RATE_TQ ("SDR"),
.DATA_WIDTH (8),
.INTERFACE_TYPE ("DEFAULT"),
.TRISTATE_WIDTH (1),
.SERDES_MODE ("SLAVE"))
i_serdes_s (
.D1 (1'b0),
.D2 (1'b0),
.D3 (data_s6[l_inst]),
.D4 (data_s7[l_inst]),
.D5 (1'b0),
.D6 (1'b0),
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
.SHIFTOUT1 (serdes_shift1_s[l_inst]),
.SHIFTOUT2 (serdes_shift2_s[l_inst]),
.OCE (1'b1),
.CLK (clk),
.CLKDIV (div_clk),
.CLKPERF (1'b0),
.CLKPERFDELAY (1'b0),
.WC (1'b0),
.ODV (1'b0),
.OQ (),
.TQ (),
.OCBEXTEND (),
.OFB (),
.TFB (),
.TCE (1'b0),
.RST (rst));
end
OBUFDS i_obuf (
.I (data_out_s[l_inst]),
.O (data_out_p[l_inst]),
.OB (data_out_n[l_inst]));
end
endgenerate
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,151 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Input must be RGB or CrYCb in that order, output is CrY/CbY
module ad_ss_444to422 (
// 444 inputs
clk,
s444_de,
s444_sync,
s444_data,
// 422 outputs
s422_sync,
s422_data);
// parameters
parameter Cr_Cb_N = 0;
parameter DELAY_DATA_WIDTH = 16;
localparam DW = DELAY_DATA_WIDTH - 1;
// 444 inputs
input clk;
input s444_de;
input [DW:0] s444_sync;
input [23:0] s444_data;
// 422 outputs
output [DW:0] s422_sync;
output [15:0] s422_data;
// internal registers
reg s444_de_d = 'd0;
reg [DW:0] s444_sync_d = 'd0;
reg [23:0] s444_data_d = 'd0;
reg s444_de_2d = 'd0;
reg [DW:0] s444_sync_2d = 'd0;
reg [23:0] s444_data_2d = 'd0;
reg s444_de_3d = 'd0;
reg [DW:0] s444_sync_3d = 'd0;
reg [23:0] s444_data_3d = 'd0;
reg [ 7:0] cr = 'd0;
reg [ 7:0] cb = 'd0;
reg cr_cb_sel = 'd0;
reg [DW:0] s422_sync = 'd0;
reg [15:0] s422_data = 'd0;
// internal wires
wire [ 9:0] cr_s;
wire [ 9:0] cb_s;
// fill the data pipe lines, hold the last data on edges
always @(posedge clk) begin
s444_de_d <= s444_de;
s444_sync_d <= s444_sync;
if (s444_de == 1'b1) begin
s444_data_d <= s444_data;
end
s444_de_2d <= s444_de_d;
s444_sync_2d <= s444_sync_d;
if (s444_de_d == 1'b1) begin
s444_data_2d <= s444_data_d;
end
s444_de_3d <= s444_de_2d;
s444_sync_3d <= s444_sync_2d;
if (s444_de_2d == 1'b1) begin
s444_data_3d <= s444_data_2d;
end
end
// get the average 0.25*s(n-1) + 0.5*s(n) + 0.25*s(n+1)
assign cr_s = {2'd0, s444_data_d[23:16]} +
{2'd0, s444_data_3d[23:16]} +
{1'd0, s444_data_2d[23:16], 1'd0};
assign cb_s = {2'd0, s444_data_d[7:0]} +
{2'd0, s444_data_3d[7:0]} +
{1'd0, s444_data_2d[7:0], 1'd0};
always @(posedge clk) begin
cr <= cr_s[9:2];
cb <= cb_s[9:2];
if (s444_de_3d == 1'b1) begin
cr_cb_sel <= ~cr_cb_sel;
end else begin
cr_cb_sel <= Cr_Cb_N;
end
end
// 422 outputs
always @(posedge clk) begin
s422_sync <= s444_sync_3d;
if (s444_de_3d == 1'b0) begin
s422_data <= 'd0;
end else if (cr_cb_sel == 1'b1) begin
s422_data <= {cr, s444_data_3d[15:8]};
end else begin
s422_data <= {cb, s444_data_3d[15:8]};
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,151 @@
-- ***************************************************************************
-- ***************************************************************************
-- Copyright 2013(c) Analog Devices, Inc.
-- Author: Lars-Peter Clausen <lars-peter.clausen@analog.com>
--
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
-- - Neither the name of Analog Devices, Inc. nor the names of its
-- contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- - The use of this software may or may not infringe the patent rights
-- of one or more patent holders. This license does not release you
-- from the requirement that you obtain separate licenses from these
-- patent holders to use this software.
-- - Use of the software either in source or binary form, must be run
-- on or directly connected to an Analog Devices Inc. component.
--
-- THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED.
--
-- IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
-- RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axi_ctrlif is
generic
(
C_NUM_REG : integer := 32;
C_S_AXI_DATA_WIDTH : integer := 32;
C_S_AXI_ADDR_WIDTH : integer := 32;
C_FAMILY : string := "virtex6"
);
port
(
-- AXI bus interface
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_BREADY : in std_logic;
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_RREADY : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_WREADY : out std_logic;
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_AWREADY : out std_logic;
rd_addr : out integer range 0 to C_NUM_REG - 1;
rd_data : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
rd_ack : out std_logic;
rd_stb : in std_logic;
wr_addr : out integer range 0 to C_NUM_REG - 1;
wr_data : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
wr_ack : in std_logic;
wr_stb : out std_logic
);
end entity axi_ctrlif;
architecture Behavioral of axi_ctrlif is
type state_type is (IDLE, RESP, ACK);
signal rd_state : state_type;
signal wr_state : state_type;
begin
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
rd_state <= IDLE;
else
case rd_state is
when IDLE =>
if S_AXI_ARVALID = '1' then
rd_state <= RESP;
rd_addr <= to_integer(unsigned(S_AXI_ARADDR((C_S_AXI_ADDR_WIDTH-1) downto 2)));
end if;
when RESP =>
if rd_stb = '1' and S_AXI_RREADY = '1' then
rd_state <= IDLE;
end if;
when others => null;
end case;
end if;
end if;
end process;
S_AXI_ARREADY <= '1' when rd_state = IDLE else '0';
S_AXI_RVALID <= '1' when rd_state = RESP and rd_stb = '1' else '0';
S_AXI_RRESP <= "00";
rd_ack <= '1' when rd_state = RESP and S_AXI_RREADY = '1' else '0';
S_AXI_RDATA <= rd_data;
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
wr_state <= IDLE;
else
case wr_state is
when IDLE =>
if S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and wr_ack = '1' then
wr_state <= ACK;
end if;
when ACK =>
wr_state <= RESP;
when RESP =>
if S_AXI_BREADY = '1' then
wr_state <= IDLE;
end if;
end case;
end if;
end if;
end process;
wr_stb <= '1' when S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and wr_state = IDLE else '0';
wr_data <= S_AXI_WDATA;
wr_addr <= to_integer(unsigned(S_AXI_AWADDR((C_S_AXI_ADDR_WIDTH-1) downto 2)));
S_AXI_AWREADY <= '1' when wr_state = ACK else '0';
S_AXI_WREADY <= '1' when wr_state = ACK else '0';
S_AXI_BRESP <= "00";
S_AXI_BVALID <= '1' when wr_state = RESP else '0';
end;

View File

@ -0,0 +1,80 @@
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.dma_fifo;
entity axi_streaming_dma_rx_fifo is
generic (
RAM_ADDR_WIDTH : integer := 3;
FIFO_DWIDTH : integer := 32
);
port (
clk : in std_logic;
resetn : in std_logic;
fifo_reset : in std_logic;
-- Enable DMA interface
enable : in Boolean;
period_len : in integer range 0 to 65535;
-- Read port
M_AXIS_ACLK : in std_logic;
M_AXIS_TREADY : in std_logic;
M_AXIS_TDATA : out std_logic_vector(FIFO_DWIDTH-1 downto 0);
M_AXIS_TLAST : out std_logic;
M_AXIS_TVALID : out std_logic;
M_AXIS_TKEEP : out std_logic_vector(3 downto 0);
-- Write port
in_stb : in std_logic;
in_ack : out std_logic;
in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0)
);
end;
architecture imp of axi_streaming_dma_rx_fifo is
signal out_stb : std_logic;
signal period_count : integer range 0 to 65535;
signal last : std_logic;
begin
M_AXIS_TVALID <= out_stb;
fifo: entity dma_fifo
generic map (
RAM_ADDR_WIDTH => RAM_ADDR_WIDTH,
FIFO_DWIDTH => FIFO_DWIDTH
)
port map (
clk => clk,
resetn => resetn,
fifo_reset => fifo_reset,
in_stb => in_stb,
in_ack => in_ack,
in_data => in_data,
out_stb => out_stb,
out_ack => M_AXIS_TREADY,
out_data => M_AXIS_TDATA
);
M_AXIS_TKEEP <= "1111";
M_AXIS_TLAST <= '1' when period_count = 0 else '0';
period_counter: process(M_AXIS_ACLK) is
begin
if resetn = '0' then
period_count <= period_len;
else
if out_stb = '1' and M_AXIS_TREADY = '1' then
if period_count = 0 then
period_count <= period_len;
else
period_count <= period_count - 1;
end if;
end if;
end if;
end process;
end;

View File

@ -0,0 +1,74 @@
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.dma_fifo;
entity axi_streaming_dma_tx_fifo is
generic (
RAM_ADDR_WIDTH : integer := 3;
FIFO_DWIDTH : integer := 32
);
port (
clk : in std_logic;
resetn : in std_logic;
fifo_reset : in std_logic;
-- Enable DMA interface
enable : in Boolean;
-- Write port
S_AXIS_ACLK : in std_logic;
S_AXIS_TREADY : out std_logic;
S_AXIS_TDATA : in std_logic_vector(FIFO_DWIDTH-1 downto 0);
S_AXIS_TLAST : in std_logic;
S_AXIS_TVALID : in std_logic;
-- Read port
out_stb : out std_logic;
out_ack : in std_logic;
out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0)
);
end;
architecture imp of axi_streaming_dma_tx_fifo is
signal in_ack : std_logic;
signal drain_dma : Boolean;
begin
fifo: entity dma_fifo
generic map (
RAM_ADDR_WIDTH => RAM_ADDR_WIDTH,
FIFO_DWIDTH => FIFO_DWIDTH
)
port map (
clk => clk,
resetn => resetn,
fifo_reset => fifo_reset,
in_stb => S_AXIS_TVALID,
in_ack => in_ack,
in_data => S_AXIS_TDATA,
out_stb => out_stb,
out_ack => out_ack,
out_data => out_data
);
drain_process: process (S_AXIS_ACLK) is
variable enable_d1 : Boolean;
begin
if rising_edge(S_AXIS_ACLK) then
if resetn = '0' then
drain_dma <= False;
else
if S_AXIS_TLAST = '1' then
drain_dma <= False;
elsif enable_d1 and enable then
drain_dma <= True;
end if;
enable_d1 := enable;
end if;
end if;
end process;
S_AXIS_TREADY <= '1' when in_ack = '1' or drain_dma else '0';
end;

View File

@ -0,0 +1,69 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dma_fifo is
generic (
RAM_ADDR_WIDTH : integer := 3;
FIFO_DWIDTH : integer := 32
);
port (
clk : in std_logic;
resetn : in std_logic;
fifo_reset : in std_logic;
-- Write port
in_stb : in std_logic;
in_ack : out std_logic;
in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0);
-- Read port
out_stb : out std_logic;
out_ack : in std_logic;
out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0)
);
end;
architecture imp of dma_fifo is
constant FIFO_MAX : natural := 2**RAM_ADDR_WIDTH -1;
type MEM is array (0 to FIFO_MAX) of std_logic_vector(FIFO_DWIDTH - 1 downto 0);
signal data_fifo : MEM;
signal wr_addr : natural range 0 to FIFO_MAX;
signal rd_addr : natural range 0 to FIFO_MAX;
signal full, empty : Boolean;
begin
in_ack <= '0' when full else '1';
out_stb <= '0' when empty else '1';
out_data <= data_fifo(rd_addr);
fifo: process (clk) is
variable free_cnt : integer range 0 to FIFO_MAX + 1;
begin
if rising_edge(clk) then
if (resetn = '0') or (fifo_reset = '1') then
wr_addr <= 0;
rd_addr <= 0;
free_cnt := FIFO_MAX + 1;
empty <= True;
full <= False;
else
if in_stb = '1' and not full then
data_fifo(wr_addr) <= in_data;
wr_addr <= (wr_addr + 1) mod (FIFO_MAX + 1);
free_cnt := free_cnt - 1;
end if;
if out_ack = '1' and not empty then
rd_addr <= (rd_addr + 1) mod (FIFO_MAX + 1);
free_cnt := free_cnt + 1;
end if;
full <= free_cnt = 0;
empty <= free_cnt = FIFO_MAX + 1;
end if;
end if;
end process;
end;

View File

@ -0,0 +1,140 @@
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.dma_fifo;
entity pl330_dma_fifo is
generic (
RAM_ADDR_WIDTH : integer := 3;
FIFO_DWIDTH : integer := 32;
FIFO_DIRECTION : integer := 0 -- 0 = write FIFO, 1 = read FIFO
);
port (
clk : in std_logic;
resetn : in std_logic;
fifo_reset : in std_logic;
-- Enable DMA interface
enable : in Boolean;
-- Write port
in_stb : in std_logic;
in_ack : out std_logic;
in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0);
-- Read port
out_stb : out std_logic;
out_ack : in std_logic;
out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0);
-- PL330 DMA interface
dclk : in std_logic;
dresetn : in std_logic;
davalid : in std_logic;
daready : out std_logic;
datype : in std_logic_vector(1 downto 0);
drvalid : out std_logic;
drready : in std_logic;
drtype : out std_logic_vector(1 downto 0);
drlast : out std_logic;
DBG : out std_logic_vector(7 downto 0)
);
end;
architecture imp of pl330_dma_fifo is
signal request_data : Boolean;
type state_type is (IDLE, REQUEST, WAITING, FLUSH);
signal state : state_type;
signal i_in_ack : std_logic;
signal i_out_stb : std_logic;
begin
in_ack <= i_in_ack;
out_stb <= i_out_stb;
fifo: entity dma_fifo
generic map (
RAM_ADDR_WIDTH => RAM_ADDR_WIDTH,
FIFO_DWIDTH => FIFO_DWIDTH
)
port map (
clk => clk,
resetn => resetn,
fifo_reset => fifo_reset,
in_stb => in_stb,
in_ack => i_in_ack,
in_data => in_data,
out_stb => i_out_stb,
out_ack => out_ack,
out_data => out_data
);
request_data <= i_in_ack = '1' when FIFO_DIRECTION = 0 else i_out_stb = '1';
drlast <= '0';
daready <= '1';
drvalid <= '1' when (state = REQUEST) or (state = FLUSH) else '0';
drtype <= "00" when state = REQUEST else "10";
DBG(0) <= davalid;
DBG(2 downto 1) <= datype;
DBG(3) <= '1' when request_data else '0';
process (state)
begin
case state is
when IDLE => DBG(5 downto 4) <= "00";
when REQUEST => DBG(5 downto 4) <= "01";
when WAITING => DBG(5 downto 4) <= "10";
when FLUSH => DBG(5 downto 4) <= "11";
end case;
end process;
pl330_req_fsm: process (dclk) is
begin
if rising_edge(dclk) then
if dresetn = '0' then
state <= IDLE;
else
-- The controller may send a FLUSH request at any time and it won't
-- respond to any of our requests until we've ack the FLUSH request.
-- The FLUSH request is also supposed to reset our state machine, so
-- go back to idle after having acked the FLUSH.
if davalid = '1' and datype = "10" then
state <= FLUSH;
else
case state is
-- Nothing to do, wait for the fifo to run empty
when IDLE =>
if request_data and enable then
state <= REQUEST;
end if;
-- Send out a request to the PL330
when REQUEST =>
if drready = '1' then
state <= WAITING;
end if;
-- Wait for a ACK from the PL330 that it did transfer the data
when WAITING =>
if fifo_reset = '1' then
state <= IDLE;
elsif davalid = '1' then
if datype = "00" then
state <= IDLE;
end if;
end if;
-- Send out an ACK for the flush
when FLUSH =>
if drready = '1' then
state <= IDLE;
end if;
end case;
end if;
end if;
end if;
end process;
end;

View File

@ -0,0 +1,76 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
/*
* Helper module for synchronizing bit signals from one clock domain to another.
* It uses the standard approach of 2 FF in series.
* Note, that while the module allows to synchronize multiple bits at once it is
* only able to synchronize multi-bit signals where at max one bit changes per
* clock cycle (e.g. a gray counter).
*/
module sync_bits
(
input [NUM_BITS-1:0] in,
input out_resetn,
input out_clk,
output [NUM_BITS-1:0] out
);
// Number of bits to synchronize
parameter NUM_BITS = 1;
// Whether input and output clocks are asynchronous, if 0 the synchronizer will
// be bypassed and the output signal equals the input signal.
parameter CLK_ASYNC = 1;
reg [NUM_BITS-1:0] out_m1 = 'h0;
reg [NUM_BITS-1:0] out_m2 = 'h0;
always @(posedge out_clk)
begin
if (out_resetn == 1'b0) begin
out_m1 <= 'b0;
out_m2 <= 'b0;
end else begin
out_m1 <= in;
out_m2 <= out_m1;
end
end
assign out = CLK_ASYNC ? out_m2 : in;
endmodule

111
library/common/sync_gray.v Normal file
View File

@ -0,0 +1,111 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2013(c) Analog Devices, Inc.
// Author: Lars-Peter Clausen <lars@metafoo.de>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
/*
* Helper module for synchronizing a counter from one clock domain to another
* using gray code. To work correctly the counter must not change its value by
* more than one in one clock cycle in the source domain. I.e. the value may
* change by either -1, 0 or +1.
*/
module sync_gray (
input in_clk,
input in_resetn,
input [DATA_WIDTH-1:0] in_count,
input out_resetn,
input out_clk,
output [DATA_WIDTH-1:0] out_count
);
// Bit-width of the counter
parameter DATA_WIDTH = 1;
// Whether the input and output clock are asynchronous, if set to 0 the
// synchronizer will be bypassed and out_count will be in_count.
parameter CLK_ASYNC = 1;
reg [DATA_WIDTH-1:0] in_count_gray = 'h0;
reg [DATA_WIDTH-1:0] out_count_gray_m1 = 'h0;
reg [DATA_WIDTH-1:0] out_count_gray_m2 = 'h0;
reg [DATA_WIDTH-1:0] out_count_m = 'h0;
function [DATA_WIDTH-1:0] g2b;
input [DATA_WIDTH-1:0] g;
reg [DATA_WIDTH-1:0] b;
integer i;
begin
b[DATA_WIDTH-1] = g[DATA_WIDTH-1];
for (i = DATA_WIDTH - 2; i >= 0; i = i - 1)
b[i] = b[i + 1] ^ g[i];
g2b = b;
end
endfunction
function [DATA_WIDTH-1:0] b2g;
input [DATA_WIDTH-1:0] b;
reg [DATA_WIDTH-1:0] g;
integer i;
begin
g[DATA_WIDTH-1] = b[DATA_WIDTH-1];
for (i = DATA_WIDTH - 2; i >= 0; i = i -1)
g[i] = b[i + 1] ^ b[i];
b2g = g;
end
endfunction
always @(posedge in_clk) begin
if (in_resetn == 1'b0) begin
in_count_gray <= 'h00;
end else begin
in_count_gray <= b2g(in_count);
end
end
always @(posedge out_clk) begin
if (out_resetn == 1'b0) begin
out_count_gray_m1 <= 'h00;
out_count_gray_m2 <= 'h00;
out_count_m <= 'h00;
end else begin
out_count_gray_m1 <= in_count_gray;
out_count_gray_m2 <= out_count_gray_m1;
out_count_m <= g2b(out_count_gray_m2);
end
end
assign out_count = CLK_ASYNC ? out_count_m : in_count;
endmodule

View File

@ -0,0 +1,339 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_adc_channel (
// adc interface
adc_clk,
adc_rst,
adc_enable,
adc_pn_sel,
adc_iqcor_enb,
adc_dcfilt_enb,
adc_dfmt_se,
adc_dfmt_type,
adc_dfmt_enable,
adc_pn_type,
adc_dcfilt_offset,
adc_dcfilt_coeff,
adc_iqcor_coeff_1,
adc_iqcor_coeff_2,
adc_pn_err,
adc_pn_oos,
adc_or,
up_adc_pn_err,
up_adc_pn_oos,
up_adc_or,
// user controls
up_usr_datatype_be,
up_usr_datatype_signed,
up_usr_datatype_shift,
up_usr_datatype_total_bits,
up_usr_datatype_bits,
up_usr_decimation_m,
up_usr_decimation_n,
adc_usr_datatype_be,
adc_usr_datatype_signed,
adc_usr_datatype_shift,
adc_usr_datatype_total_bits,
adc_usr_datatype_bits,
adc_usr_decimation_m,
adc_usr_decimation_n,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_ADC_CHID = 4'h0;
// adc interface
input adc_clk;
input adc_rst;
output adc_enable;
output adc_pn_sel;
output adc_iqcor_enb;
output adc_dcfilt_enb;
output adc_dfmt_se;
output adc_dfmt_type;
output adc_dfmt_enable;
output adc_pn_type;
output [15:0] adc_dcfilt_offset;
output [15:0] adc_dcfilt_coeff;
output [15:0] adc_iqcor_coeff_1;
output [15:0] adc_iqcor_coeff_2;
input adc_pn_err;
input adc_pn_oos;
input adc_or;
output up_adc_pn_err;
output up_adc_pn_oos;
output up_adc_or;
// user controls
output up_usr_datatype_be;
output up_usr_datatype_signed;
output [ 7:0] up_usr_datatype_shift;
output [ 7:0] up_usr_datatype_total_bits;
output [ 7:0] up_usr_datatype_bits;
output [15:0] up_usr_decimation_m;
output [15:0] up_usr_decimation_n;
input adc_usr_datatype_be;
input adc_usr_datatype_signed;
input [ 7:0] adc_usr_datatype_shift;
input [ 7:0] adc_usr_datatype_total_bits;
input [ 7:0] adc_usr_datatype_bits;
input [15:0] adc_usr_decimation_m;
input [15:0] adc_usr_decimation_n;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg up_adc_pn_sel = 'd0;
reg up_adc_iqcor_enb = 'd0;
reg up_adc_dcfilt_enb = 'd0;
reg up_adc_dfmt_se = 'd0;
reg up_adc_dfmt_type = 'd0;
reg up_adc_dfmt_enable = 'd0;
reg up_adc_pn_type = 'd0;
reg up_adc_enable = 'd0;
reg up_adc_pn_err = 'd0;
reg up_adc_pn_oos = 'd0;
reg up_adc_or = 'd0;
reg [15:0] up_adc_dcfilt_offset = 'd0;
reg [15:0] up_adc_dcfilt_coeff = 'd0;
reg [15:0] up_adc_iqcor_coeff_1 = 'd0;
reg [15:0] up_adc_iqcor_coeff_2 = 'd0;
reg up_usr_datatype_be = 'd0;
reg up_usr_datatype_signed = 'd0;
reg [ 7:0] up_usr_datatype_shift = 'd0;
reg [ 7:0] up_usr_datatype_total_bits = 'd0;
reg [ 7:0] up_usr_datatype_bits = 'd0;
reg [15:0] up_usr_decimation_m = 'd0;
reg [15:0] up_usr_decimation_n = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_adc_pn_err_s;
wire up_adc_pn_oos_s;
wire up_adc_or_s;
// decode block select
assign up_sel_s = ((up_addr[13:8] == 6'h01) && (up_addr[7:4] == PCORE_ADC_CHID)) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_adc_pn_sel <= 'd0;
up_adc_iqcor_enb <= 'd0;
up_adc_dcfilt_enb <= 'd0;
up_adc_dfmt_se <= 'd0;
up_adc_dfmt_type <= 'd0;
up_adc_dfmt_enable <= 'd0;
up_adc_pn_type <= 'd0;
up_adc_enable <= 'd0;
up_adc_pn_err <= 'd0;
up_adc_pn_oos <= 'd0;
up_adc_or <= 'd0;
up_adc_dcfilt_offset <= 'd0;
up_adc_dcfilt_coeff <= 'd0;
up_adc_iqcor_coeff_1 <= 'd0;
up_adc_iqcor_coeff_2 <= 'd0;
up_usr_datatype_be <= 'd0;
up_usr_datatype_signed <= 'd0;
up_usr_datatype_shift <= 'd0;
up_usr_datatype_total_bits <= 'd0;
up_usr_datatype_bits <= 'd0;
up_usr_decimation_m <= 'd0;
up_usr_decimation_n <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h0)) begin
up_adc_pn_sel <= up_wdata[10];
up_adc_iqcor_enb <= up_wdata[9];
up_adc_dcfilt_enb <= up_wdata[8];
up_adc_dfmt_se <= up_wdata[6];
up_adc_dfmt_type <= up_wdata[5];
up_adc_dfmt_enable <= up_wdata[4];
up_adc_pn_type <= up_wdata[1];
up_adc_enable <= up_wdata[0];
end
if (up_adc_pn_err_s == 1'b1) begin
up_adc_pn_err <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h1)) begin
up_adc_pn_err <= up_adc_pn_err & ~up_wdata[2];
end
if (up_adc_pn_oos_s == 1'b1) begin
up_adc_pn_oos <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h1)) begin
up_adc_pn_oos <= up_adc_pn_oos & ~up_wdata[1];
end
if (up_adc_or_s == 1'b1) begin
up_adc_or <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h1)) begin
up_adc_or <= up_adc_or & ~up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h4)) begin
up_adc_dcfilt_offset <= up_wdata[31:16];
up_adc_dcfilt_coeff <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h5)) begin
up_adc_iqcor_coeff_1 <= up_wdata[31:16];
up_adc_iqcor_coeff_2 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h8)) begin
up_usr_datatype_be <= up_wdata[25];
up_usr_datatype_signed <= up_wdata[24];
up_usr_datatype_shift <= up_wdata[23:16];
up_usr_datatype_total_bits <= up_wdata[15:8];
up_usr_datatype_bits <= up_wdata[7:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h9)) begin
up_usr_decimation_m <= up_wdata[31:16];
up_usr_decimation_n <= up_wdata[15:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[3:0])
4'h0: up_rdata <= {21'd0, up_adc_pn_sel, up_adc_iqcor_enb, up_adc_dcfilt_enb,
1'd0, up_adc_dfmt_se, up_adc_dfmt_type, up_adc_dfmt_enable,
2'd0, up_adc_pn_type, up_adc_enable};
4'h1: up_rdata <= {29'd0, up_adc_pn_err, up_adc_pn_oos, up_adc_or};
4'h4: up_rdata <= {up_adc_dcfilt_offset, up_adc_dcfilt_coeff};
4'h5: up_rdata <= {up_adc_iqcor_coeff_1, up_adc_iqcor_coeff_2};
4'h8: up_rdata <= {6'd0, adc_usr_datatype_be, adc_usr_datatype_signed,
adc_usr_datatype_shift, adc_usr_datatype_total_bits,
adc_usr_datatype_bits};
4'h9: up_rdata <= {adc_usr_decimation_m, adc_usr_decimation_n};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// adc control & status
up_xfer_cntrl #(.DATA_WIDTH(72)) i_adc_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_adc_pn_sel,
up_adc_iqcor_enb,
up_adc_dcfilt_enb,
up_adc_dfmt_se,
up_adc_dfmt_type,
up_adc_dfmt_enable,
up_adc_pn_type,
up_adc_enable,
up_adc_dcfilt_offset,
up_adc_dcfilt_coeff,
up_adc_iqcor_coeff_1,
up_adc_iqcor_coeff_2}),
.d_rst (adc_rst),
.d_clk (adc_clk),
.d_data_cntrl ({ adc_pn_sel,
adc_iqcor_enb,
adc_dcfilt_enb,
adc_dfmt_se,
adc_dfmt_type,
adc_dfmt_enable,
adc_pn_type,
adc_enable,
adc_dcfilt_offset,
adc_dcfilt_coeff,
adc_iqcor_coeff_1,
adc_iqcor_coeff_2}));
up_xfer_status #(.DATA_WIDTH(3)) i_adc_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_adc_pn_err_s,
up_adc_pn_oos_s,
up_adc_or_s}),
.d_rst (adc_rst),
.d_clk (adc_clk),
.d_data_status ({ adc_pn_err,
adc_pn_oos,
adc_or}));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,406 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_adc_common (
// clock reset
mmcm_rst,
// adc interface
adc_clk,
adc_rst,
adc_r1_mode,
adc_ddr_edgesel,
adc_pin_mode,
adc_status,
adc_status_pn_err,
adc_status_pn_oos,
adc_status_or,
adc_status_ovf,
adc_status_unf,
adc_clk_ratio,
// delay interface
delay_clk,
delay_rst,
delay_sel,
delay_rwn,
delay_addr,
delay_wdata,
delay_rdata,
delay_ack_t,
delay_locked,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked,
// user channel control
up_usr_chanmax,
adc_usr_chanmax,
dma_bw,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00040062;
parameter PCORE_ID = 0;
// clock reset
output mmcm_rst;
// adc interface
input adc_clk;
output adc_rst;
output adc_r1_mode;
output adc_ddr_edgesel;
output adc_pin_mode;
input adc_status;
input adc_status_pn_err;
input adc_status_pn_oos;
input adc_status_or;
input adc_status_ovf;
input adc_status_unf;
input [31:0] adc_clk_ratio;
// delay interface
input delay_clk;
output delay_rst;
output delay_sel;
output delay_rwn;
output [ 7:0] delay_addr;
output [ 4:0] delay_wdata;
input [ 4:0] delay_rdata;
input delay_ack_t;
input delay_locked;
// drp interface
input drp_clk;
output drp_rst;
output drp_sel;
output drp_wr;
output [11:0] drp_addr;
output [15:0] drp_wdata;
input [15:0] drp_rdata;
input drp_ready;
input drp_locked;
// user channel control
output [ 7:0] up_usr_chanmax;
input [ 7:0] adc_usr_chanmax;
input [31:0] dma_bw;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_mmcm_resetn = 'd0;
reg up_resetn = 'd0;
reg up_adc_r1_mode = 'd0;
reg up_adc_ddr_edgesel = 'd0;
reg up_adc_pin_mode = 'd0;
reg up_delay_sel = 'd0;
reg up_delay_rwn = 'd0;
reg [ 7:0] up_delay_addr = 'd0;
reg [ 4:0] up_delay_wdata = 'd0;
reg up_drp_sel_t = 'd0;
reg up_drp_rwn = 'd0;
reg [11:0] up_drp_addr = 'd0;
reg [15:0] up_drp_wdata = 'd0;
reg up_status_ovf = 'd0;
reg up_status_unf = 'd0;
reg [ 7:0] up_usr_chanmax = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_mmcm_preset_s;
wire up_status_pn_err_s;
wire up_status_pn_oos_s;
wire up_status_or_s;
wire up_status_s;
wire [31:0] up_adc_clk_count_s;
wire [ 4:0] up_delay_rdata_s;
wire up_delay_status_s;
wire up_delay_locked_s;
wire [15:0] up_drp_rdata_s;
wire up_drp_status_s;
wire up_drp_locked_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h00) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
assign up_mmcm_preset_s = ~up_mmcm_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_mmcm_resetn <= 'd0;
up_resetn <= 'd0;
up_adc_r1_mode <= 'd0;
up_adc_ddr_edgesel <= 'd0;
up_adc_pin_mode <= 'd0;
up_delay_sel <= 'd0;
up_delay_rwn <= 'd0;
up_delay_addr <= 'd0;
up_delay_wdata <= 'd0;
up_drp_sel_t <= 'd0;
up_drp_rwn <= 'd0;
up_drp_addr <= 'd0;
up_drp_wdata <= 'd0;
up_status_ovf <= 'd0;
up_status_unf <= 'd0;
up_usr_chanmax <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h10)) begin
up_mmcm_resetn <= up_wdata[1];
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h11)) begin
up_adc_r1_mode <= up_wdata[2];
up_adc_ddr_edgesel <= up_wdata[1];
up_adc_pin_mode <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h18)) begin
up_delay_sel <= up_wdata[17];
up_delay_rwn <= up_wdata[16];
up_delay_addr <= up_wdata[15:8];
up_delay_wdata <= up_wdata[4:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1c)) begin
up_drp_sel_t <= ~up_drp_sel_t;
up_drp_rwn <= up_wdata[28];
up_drp_addr <= up_wdata[27:16];
up_drp_wdata <= up_wdata[15:0];
end
if (up_status_ovf_s == 1'b1) begin
up_status_ovf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_status_ovf <= up_status_ovf & ~up_wdata[2];
end
if (up_status_unf_s == 1'b1) begin
up_status_unf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_status_unf <= up_status_unf & ~up_wdata[1];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h28)) begin
up_usr_chanmax <= up_wdata[7:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h10: up_rdata <= {30'd0, up_mmcm_resetn, up_resetn};
8'h11: up_rdata <= {29'd0, up_adc_r1_mode, up_adc_ddr_edgesel, up_adc_pin_mode};
8'h15: up_rdata <= up_adc_clk_count_s;
8'h16: up_rdata <= adc_clk_ratio;
8'h17: up_rdata <= {28'd0, up_status_pn_err_s, up_status_pn_oos_s, up_status_or_s, up_status_s};
8'h18: up_rdata <= {14'd0, up_delay_sel, up_delay_rwn, up_delay_addr, 3'd0, up_delay_wdata};
8'h19: up_rdata <= {22'd0, up_delay_locked_s, up_delay_status_s, 3'd0, up_delay_rdata_s};
8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata};
8'h1d: up_rdata <= {14'd0, up_drp_locked_s, up_drp_status_s, up_drp_rdata_s};
8'h22: up_rdata <= {29'd0, up_status_ovf, up_status_unf, 1'b0};
8'h23: up_rdata <= dma_bw;
8'h28: up_rdata <= {24'd0, adc_usr_chanmax};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_mmcm_rst_reg (.preset(up_mmcm_preset_s), .clk(drp_clk), .rst(mmcm_rst));
ad_rst i_adc_rst_reg (.preset(up_preset_s), .clk(adc_clk), .rst(adc_rst));
ad_rst i_delay_rst_reg (.preset(up_preset_s), .clk(delay_clk), .rst(delay_rst));
ad_rst i_drp_rst_reg (.preset(up_preset_s), .clk(drp_clk), .rst(drp_rst));
// adc control & status
up_xfer_cntrl #(.DATA_WIDTH(3)) i_adc_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_adc_r1_mode,
up_adc_ddr_edgesel,
up_adc_pin_mode}),
.d_rst (adc_rst),
.d_clk (adc_clk),
.d_data_cntrl ({ adc_r1_mode,
adc_ddr_edgesel,
adc_pin_mode}));
up_xfer_status #(.DATA_WIDTH(6)) i_adc_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_status_pn_err_s,
up_status_pn_oos_s,
up_status_or_s,
up_status_s,
up_status_ovf_s,
up_status_unf_s}),
.d_rst (adc_rst),
.d_clk (adc_clk),
.d_data_status ({ adc_status_pn_err,
adc_status_pn_oos,
adc_status_or,
adc_status,
adc_status_ovf,
adc_status_unf}));
// adc clock monitor
up_clock_mon i_adc_clock_mon (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_d_count (up_adc_clk_count_s),
.d_rst (adc_rst),
.d_clk (adc_clk));
// delay control & status
up_delay_cntrl i_delay_cntrl (
.delay_clk (delay_clk),
.delay_rst (delay_rst),
.delay_sel (delay_sel),
.delay_rwn (delay_rwn),
.delay_addr (delay_addr),
.delay_wdata (delay_wdata),
.delay_rdata (delay_rdata),
.delay_ack_t (delay_ack_t),
.delay_locked (delay_locked),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_delay_sel (up_delay_sel),
.up_delay_rwn (up_delay_rwn),
.up_delay_addr (up_delay_addr),
.up_delay_wdata (up_delay_wdata),
.up_delay_rdata (up_delay_rdata_s),
.up_delay_status (up_delay_status_s),
.up_delay_locked (up_delay_locked_s));
// drp control & status
up_drp_cntrl i_drp_cntrl (
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel),
.drp_wr (drp_wr),
.drp_addr (drp_addr),
.drp_wdata (drp_wdata),
.drp_rdata (drp_rdata),
.drp_ready (drp_ready),
.drp_locked (drp_locked),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_drp_sel_t (up_drp_sel_t),
.up_drp_rwn (up_drp_rwn),
.up_drp_addr (up_drp_addr),
.up_drp_wdata (up_drp_wdata),
.up_drp_rdata (up_drp_rdata_s),
.up_drp_status (up_drp_status_s),
.up_drp_locked (up_drp_locked_s));
endmodule
// ***************************************************************************
// ***************************************************************************

261
library/common/up_axi.v Normal file
View File

@ -0,0 +1,261 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
module up_axi (
// reset and clocks
up_rstn,
up_clk,
// axi4 interface
up_axi_awvalid,
up_axi_awaddr,
up_axi_awready,
up_axi_wvalid,
up_axi_wdata,
up_axi_wstrb,
up_axi_wready,
up_axi_bvalid,
up_axi_bresp,
up_axi_bready,
up_axi_arvalid,
up_axi_araddr,
up_axi_arready,
up_axi_rvalid,
up_axi_rresp,
up_axi_rdata,
up_axi_rready,
// pcore interface
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_BASEADDR = 32'hffffffff;
parameter PCORE_HIGHADDR = 32'h00000000;
// reset and clocks
input up_rstn;
input up_clk;
// axi4 interface
input up_axi_awvalid;
input [31:0] up_axi_awaddr;
output up_axi_awready;
input up_axi_wvalid;
input [31:0] up_axi_wdata;
input [ 3:0] up_axi_wstrb;
output up_axi_wready;
output up_axi_bvalid;
output [ 1:0] up_axi_bresp;
input up_axi_bready;
input up_axi_arvalid;
input [31:0] up_axi_araddr;
output up_axi_arready;
output up_axi_rvalid;
output [ 1:0] up_axi_rresp;
output [31:0] up_axi_rdata;
input up_axi_rready;
// pcore interface
output up_sel;
output up_wr;
output [13:0] up_addr;
output [31:0] up_wdata;
input [31:0] up_rdata;
input up_ack;
// internal registers
reg up_axi_awready = 'd0;
reg up_axi_wready = 'd0;
reg up_axi_arready = 'd0;
reg up_axi_bvalid = 'd0;
reg up_axi_rvalid = 'd0;
reg [31:0] up_axi_rdata = 'd0;
reg up_axi_access = 'd0;
reg up_sel = 'd0;
reg up_wr = 'd0;
reg [13:0] up_addr = 'd0;
reg [31:0] up_wdata = 'd0;
reg up_access = 'd0;
reg [ 2:0] up_access_count = 'd0;
reg up_access_ack = 'd0;
reg [31:0] up_access_rdata = 'd0;
// internal wires
wire up_axi_wr_s;
wire up_axi_rd_s;
wire [31:0] up_rdata_s;
wire up_ack_s;
// responses are always okay
assign up_axi_bresp = 2'd0;
assign up_axi_rresp = 2'd0;
// wait for awvalid and wvalid before asserting awready and wready
assign up_axi_wr_s = ((up_axi_awaddr >= PCORE_BASEADDR) && (up_axi_awaddr <= PCORE_HIGHADDR)) ?
(up_axi_awvalid & up_axi_wvalid & ~up_axi_access) : 1'b0;
assign up_axi_rd_s = ((up_axi_araddr >= PCORE_BASEADDR) && (up_axi_araddr <= PCORE_HIGHADDR)) ?
(up_axi_arvalid & ~up_axi_access) : 1'b0;
// return address and data channel ready right away, response depends on ack
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_axi_awready <= 'd0;
up_axi_wready <= 'd0;
up_axi_arready <= 'd0;
up_axi_bvalid <= 'd0;
up_axi_rvalid <= 'd0;
up_axi_rdata <= 'd0;
end else begin
if ((up_axi_awready == 1'b1) && (up_axi_awvalid == 1'b1)) begin
up_axi_awready <= 1'b0;
end else if (up_axi_wr_s == 1'b1) begin
up_axi_awready <= 1'b1;
end
if ((up_axi_wready == 1'b1) && (up_axi_wvalid == 1'b1)) begin
up_axi_wready <= 1'b0;
end else if (up_axi_wr_s == 1'b1) begin
up_axi_wready <= 1'b1;
end
if ((up_axi_arready == 1'b1) && (up_axi_arvalid == 1'b1)) begin
up_axi_arready <= 1'b0;
end else if (up_axi_rd_s == 1'b1) begin
up_axi_arready <= 1'b1;
end
if ((up_axi_bready == 1'b1) && (up_axi_bvalid == 1'b1)) begin
up_axi_bvalid <= 1'b0;
end else if ((up_axi_access == 1'b1) && (up_ack_s == 1'b1) && (up_wr == 1'b1)) begin
up_axi_bvalid <= 1'b1;
end
if ((up_axi_rready == 1'b1) && (up_axi_rvalid == 1'b1)) begin
up_axi_rvalid <= 1'b0;
up_axi_rdata <= 32'd0;
end else if ((up_axi_access == 1'b1) && (up_ack_s == 1'b1) && (up_wr == 1'b0)) begin
up_axi_rvalid <= 1'b1;
up_axi_rdata <= up_rdata_s;
end
end
end
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_axi_access <= 'd0;
up_sel <= 'd0;
up_wr <= 'd0;
up_addr <= 'd0;
up_wdata <= 'd0;
end else begin
if (up_axi_access == 1'b1) begin
if (up_ack_s == 1'b1) begin
up_axi_access <= 1'b0;
end
up_sel <= 1'b0;
end else begin
up_axi_access <= up_axi_wr_s | up_axi_rd_s;
up_sel <= up_axi_wr_s | up_axi_rd_s;
end
if (up_axi_access == 1'b0) begin
up_wr <= up_axi_wr_s;
if (up_axi_wr_s == 1'b1) begin
up_addr <= up_axi_awaddr[15:2];
up_wdata <= up_axi_wdata;
end else begin
up_addr <= up_axi_araddr[15:2];
up_wdata <= 32'd0;
end
end
end
end
// combine up read and ack from all the blocks
assign up_rdata_s = up_rdata | up_access_rdata;
assign up_ack_s = up_ack | up_access_ack;
// 8 clock cycles access time out to release bus
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_access <= 'd0;
up_access_count <= 'd0;
up_access_ack <= 'd0;
up_access_rdata <= 'd0;
end else begin
if (up_sel == 1'b1) begin
up_access <= 1'b1;
end else if (up_ack_s == 1'b1) begin
up_access <= 1'b0;
end
if (up_access == 1'b1) begin
up_access_count <= up_access_count + 1'b1;
end else begin
up_access_count <= 3'd0;
end
if ((up_access_count == 3'h7) && (up_ack_s == 1'b0)) begin
up_access_ack <= 1'b1;
up_access_rdata <= {2{16'hdead}};
end else begin
up_access_ack <= 1'b0;
up_access_rdata <= 32'd0;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,241 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_axis_dma_rx (
// adc interface
adc_clk,
adc_rst,
// dma interface
dma_clk,
dma_rst,
dma_start,
dma_stream,
dma_count,
dma_ovf,
dma_unf,
dma_status,
dma_bw,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00050062;
parameter PCORE_ID = 0;
// adc interface
input adc_clk;
output adc_rst;
// dma interface
input dma_clk;
output dma_rst;
output dma_start;
output dma_stream;
output [31:0] dma_count;
input dma_ovf;
input dma_unf;
input dma_status;
input [31:0] dma_bw;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_resetn = 'd0;
reg up_dma_stream = 'd0;
reg up_dma_start = 'd0;
reg [31:0] up_dma_count = 'd0;
reg up_dma_ovf = 'd0;
reg up_dma_unf = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
reg dma_start_d = 'd0;
reg dma_start_2d = 'd0;
reg dma_start = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_dma_ovf_s;
wire up_dma_unf_s;
wire up_dma_status_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h00) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_resetn <= 'd0;
up_dma_stream <= 'd0;
up_dma_start <= 'd0;
up_dma_count <= 'd0;
up_dma_ovf <= 'd0;
up_dma_unf <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h10)) begin
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h20)) begin
up_dma_stream <= up_wdata[1];
up_dma_start <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h21)) begin
up_dma_count <= up_wdata;
end
if (up_dma_ovf_s == 1'b1) begin
up_dma_ovf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_dma_ovf <= up_dma_ovf & ~up_wdata[2];
end
if (up_dma_unf_s == 1'b1) begin
up_dma_unf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_dma_unf <= up_dma_unf & ~up_wdata[1];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h10: up_rdata <= {31'd0, up_resetn};
8'h20: up_rdata <= {30'd0, up_dma_stream, up_dma_start};
8'h21: up_rdata <= up_dma_count;
8'h22: up_rdata <= {29'd0, up_dma_ovf, up_dma_unf, up_dma_status_s};
8'h23: up_rdata <= dma_bw;
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_adc_rst_reg (.preset(up_preset_s), .clk(adc_clk), .rst(adc_rst));
ad_rst i_dma_rst_reg (.preset(up_preset_s), .clk(dma_clk), .rst(dma_rst));
// dma control & status
up_xfer_cntrl #(.DATA_WIDTH(34)) i_dma_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_dma_start,
up_dma_stream,
up_dma_count}),
.d_rst (dma_rst),
.d_clk (dma_clk),
.d_data_cntrl ({ dma_start_s,
dma_stream,
dma_count}));
up_xfer_status #(.DATA_WIDTH(3)) i_dma_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_dma_ovf_s,
up_dma_unf_s,
up_dma_status_s}),
.d_rst (dma_rst),
.d_clk (dma_clk),
.d_data_status ({ dma_ovf,
dma_unf,
dma_status}));
// start needs to be a pulse
always @(posedge dma_clk) begin
dma_start_d <= dma_start_s;
dma_start_2d <= dma_start_d;
dma_start <= dma_start_d & ~dma_start_2d;
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,205 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_axis_dma_tx (
// dac interface
dac_clk,
dac_rst,
// dma interface
dma_clk,
dma_rst,
dma_frmcnt,
dma_ovf,
dma_unf,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00050062;
parameter PCORE_ID = 0;
// dac interface
input dac_clk;
output dac_rst;
// dma interface
input dma_clk;
output dma_rst;
output [31:0] dma_frmcnt;
input dma_ovf;
input dma_unf;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_resetn = 'd0;
reg [31:0] up_dma_frmcnt = 'd0;
reg up_dma_ovf = 'd0;
reg up_dma_unf = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_dma_ovf_s;
wire up_dma_unf_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h10) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_resetn <= 'd0;
up_dma_frmcnt <= 'd0;
up_dma_ovf <= 'd0;
up_dma_unf <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h10)) begin
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h21)) begin
up_dma_frmcnt <= up_wdata;
end
if (up_dma_ovf_s == 1'b1) begin
up_dma_ovf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_dma_ovf <= up_dma_ovf & ~up_wdata[1];
end
if (up_dma_unf_s == 1'b1) begin
up_dma_unf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_dma_unf <= up_dma_unf & ~up_wdata[0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h10: up_rdata <= {31'd0, up_resetn};
8'h21: up_rdata <= up_dma_frmcnt;
8'h22: up_rdata <= {30'd0, up_dma_ovf, up_dma_unf};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_dac_rst_reg (.preset(up_preset_s), .clk(dac_clk), .rst(dac_rst));
ad_rst i_dma_rst_reg (.preset(up_preset_s), .clk(dma_clk), .rst(dma_rst));
// dma control & status
up_xfer_cntrl #(.DATA_WIDTH(32)) i_dma_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ( up_dma_frmcnt),
.d_rst (dma_rst),
.d_clk (dma_clk),
.d_data_cntrl ( dma_frmcnt));
up_xfer_status #(.DATA_WIDTH(2)) i_dma_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_dma_ovf_s,
up_dma_unf_s}),
.d_rst (dma_rst),
.d_clk (dma_clk),
.d_data_status ({ dma_ovf,
dma_unf}));
endmodule
// ***************************************************************************
// ***************************************************************************

215
library/common/up_clkgen.v Normal file
View File

@ -0,0 +1,215 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_clkgen (
// mmcm reset
mmcm_rst,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00040062;
parameter PCORE_ID = 0;
// mmcm reset
output mmcm_rst;
// drp interface
input drp_clk;
output drp_rst;
output drp_sel;
output drp_wr;
output [11:0] drp_addr;
output [15:0] drp_wdata;
input [15:0] drp_rdata;
input drp_ready;
input drp_locked;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_mmcm_resetn = 'd0;
reg up_resetn = 'd0;
reg up_drp_sel_t = 'd0;
reg up_drp_rwn = 'd0;
reg [11:0] up_drp_addr = 'd0;
reg [15:0] up_drp_wdata = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_mmcm_preset_s;
wire [15:0] up_drp_rdata_s;
wire up_drp_status_s;
wire up_drp_locked_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h00) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
assign up_mmcm_preset_s = ~up_mmcm_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_mmcm_resetn <= 'd0;
up_resetn <= 'd0;
up_drp_sel_t <= 'd0;
up_drp_rwn <= 'd0;
up_drp_addr <= 'd0;
up_drp_wdata <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h10)) begin
up_mmcm_resetn <= up_wdata[1];
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1c)) begin
up_drp_sel_t <= ~up_drp_sel_t;
up_drp_rwn <= up_wdata[28];
up_drp_addr <= up_wdata[27:16];
up_drp_wdata <= up_wdata[15:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h10: up_rdata <= {30'd0, up_mmcm_resetn, up_resetn};
8'h17: up_rdata <= {31'd0, up_drp_locked_s};
8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata};
8'h1d: up_rdata <= {14'd0, up_drp_locked_s, up_drp_status_s, up_drp_rdata_s};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_mmcm_rst_reg (.preset(up_mmcm_preset_s), .clk(drp_clk), .rst(mmcm_rst));
ad_rst i_drp_rst_reg (.preset(up_preset_s), .clk(drp_clk), .rst(drp_rst));
// drp control & status
up_drp_cntrl i_drp_cntrl (
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel),
.drp_wr (drp_wr),
.drp_addr (drp_addr),
.drp_wdata (drp_wdata),
.drp_rdata (drp_rdata),
.drp_ready (drp_ready),
.drp_locked (drp_locked),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_drp_sel_t (up_drp_sel_t),
.up_drp_rwn (up_drp_rwn),
.up_drp_addr (up_drp_addr),
.up_drp_wdata (up_drp_wdata),
.up_drp_rdata (up_drp_rdata_s),
.up_drp_status (up_drp_status_s),
.up_drp_locked (up_drp_locked_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,145 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_clock_mon (
// processor interface
up_rstn,
up_clk,
up_d_count,
// device interface
d_rst,
d_clk);
// processor interface
input up_rstn;
input up_clk;
output [31:0] up_d_count;
// device interface
input d_rst;
input d_clk;
// internal registers
reg [15:0] up_count = 'd0;
reg up_count_toggle = 'd0;
reg up_count_toggle_m1 = 'd0;
reg up_count_toggle_m2 = 'd0;
reg up_count_toggle_m3 = 'd0;
reg [31:0] up_d_count = 'd0;
reg d_count_toggle_m1 = 'd0;
reg d_count_toggle_m2 = 'd0;
reg d_count_toggle_m3 = 'd0;
reg d_count_toggle = 'd0;
reg [31:0] d_count_hold = 'd0;
reg [32:0] d_count = 'd0;
// internal signals
wire up_count_toggle_s;
wire d_count_toggle_s;
// processor reference
assign up_count_toggle_s = up_count_toggle_m3 ^ up_count_toggle_m2;
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_count <= 'd0;
up_count_toggle <= 'd0;
up_count_toggle_m1 <= 'd0;
up_count_toggle_m2 <= 'd0;
up_count_toggle_m3 <= 'd0;
up_d_count <= 'd0;
end else begin
up_count <= up_count + 1'b1;
if (up_count == 16'd0) begin
up_count_toggle <= ~up_count_toggle;
end
up_count_toggle_m1 <= d_count_toggle;
up_count_toggle_m2 <= up_count_toggle_m1;
up_count_toggle_m3 <= up_count_toggle_m2;
if (up_count_toggle_s == 1'b1) begin
up_d_count <= d_count_hold;
end
end
end
// device free running
assign d_count_toggle_s = d_count_toggle_m3 ^ d_count_toggle_m2;
always @(posedge d_clk) begin
if (d_rst == 1'b1) begin
d_count_toggle_m1 <= 'd0;
d_count_toggle_m2 <= 'd0;
d_count_toggle_m3 <= 'd0;
end else begin
d_count_toggle_m1 <= up_count_toggle;
d_count_toggle_m2 <= d_count_toggle_m1;
d_count_toggle_m3 <= d_count_toggle_m2;
end
end
always @(posedge d_clk) begin
if (d_count_toggle_s == 1'b1) begin
d_count_toggle <= ~d_count_toggle;
d_count_hold <= d_count[31:0];
end
if (d_count_toggle_s == 1'b1) begin
d_count <= 33'd1;
end else if (d_count[32] == 1'b0) begin
d_count <= d_count + 1'b1;
end else begin
d_count <= {33{1'b1}};
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,293 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_dac_channel (
// dac interface
dac_clk,
dac_rst,
dac_dds_scale_1,
dac_dds_init_1,
dac_dds_incr_1,
dac_dds_scale_2,
dac_dds_init_2,
dac_dds_incr_2,
dac_dds_patt_1,
dac_dds_patt_2,
dac_dds_sel,
dac_lb_enb,
dac_pn_enb,
// user controls
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,
dac_usr_datatype_signed,
dac_usr_datatype_shift,
dac_usr_datatype_total_bits,
dac_usr_datatype_bits,
dac_usr_interpolation_m,
dac_usr_interpolation_n,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_DAC_CHID = 4'h0;
// dac interface
input dac_clk;
input dac_rst;
output [ 3:0] dac_dds_scale_1;
output [15:0] dac_dds_init_1;
output [15:0] dac_dds_incr_1;
output [ 3:0] dac_dds_scale_2;
output [15:0] dac_dds_init_2;
output [15:0] dac_dds_incr_2;
output [15:0] dac_dds_patt_1;
output [15:0] dac_dds_patt_2;
output [ 3:0] dac_dds_sel;
output dac_lb_enb;
output dac_pn_enb;
// user controls
output up_usr_datatype_be;
output up_usr_datatype_signed;
output [ 7:0] up_usr_datatype_shift;
output [ 7:0] up_usr_datatype_total_bits;
output [ 7:0] up_usr_datatype_bits;
output [15:0] up_usr_interpolation_m;
output [15:0] up_usr_interpolation_n;
input dac_usr_datatype_be;
input dac_usr_datatype_signed;
input [ 7:0] dac_usr_datatype_shift;
input [ 7:0] dac_usr_datatype_total_bits;
input [ 7:0] dac_usr_datatype_bits;
input [15:0] dac_usr_interpolation_m;
input [15:0] dac_usr_interpolation_n;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [ 3:0] up_dac_dds_scale_1 = 'd0;
reg [15:0] up_dac_dds_init_1 = 'd0;
reg [15:0] up_dac_dds_incr_1 = 'd0;
reg [ 3:0] up_dac_dds_scale_2 = 'd0;
reg [15:0] up_dac_dds_init_2 = 'd0;
reg [15:0] up_dac_dds_incr_2 = 'd0;
reg [15:0] up_dac_dds_patt_2 = 'd0;
reg [15:0] up_dac_dds_patt_1 = 'd0;
reg up_dac_lb_enb = 'd0;
reg up_dac_pn_enb = 'd0;
reg [ 3:0] up_dac_dds_sel = 'd0;
reg up_usr_datatype_be = 'd0;
reg up_usr_datatype_signed = 'd0;
reg [ 7:0] up_usr_datatype_shift = 'd0;
reg [ 7:0] up_usr_datatype_total_bits = 'd0;
reg [ 7:0] up_usr_datatype_bits = 'd0;
reg [15:0] up_usr_interpolation_m = 'd0;
reg [15:0] up_usr_interpolation_n = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
// decode block select
assign up_sel_s = ((up_addr[13:8] == 6'h11) && (up_addr[7:4] == PCORE_DAC_CHID)) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_dac_dds_scale_1 <= 'd0;
up_dac_dds_init_1 <= 'd0;
up_dac_dds_incr_1 <= 'd0;
up_dac_dds_scale_2 <= 'd0;
up_dac_dds_init_2 <= 'd0;
up_dac_dds_incr_2 <= 'd0;
up_dac_dds_patt_2 <= 'd0;
up_dac_dds_patt_1 <= 'd0;
up_dac_lb_enb <= 'd0;
up_dac_pn_enb <= 'd0;
up_dac_dds_sel <= 'd0;
up_usr_datatype_be <= 'd0;
up_usr_datatype_signed <= 'd0;
up_usr_datatype_shift <= 'd0;
up_usr_datatype_total_bits <= 'd0;
up_usr_datatype_bits <= 'd0;
up_usr_interpolation_m <= 'd0;
up_usr_interpolation_n <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h0)) begin
up_dac_dds_scale_1 <= up_wdata[3:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h1)) begin
up_dac_dds_init_1 <= up_wdata[31:16];
up_dac_dds_incr_1 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h2)) begin
up_dac_dds_scale_2 <= up_wdata[3:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h3)) begin
up_dac_dds_init_2 <= up_wdata[31:16];
up_dac_dds_incr_2 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h4)) begin
up_dac_dds_patt_2 <= up_wdata[31:16];
up_dac_dds_patt_1 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h5)) begin
up_dac_lb_enb <= up_wdata[1];
up_dac_pn_enb <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h6)) begin
up_dac_dds_sel <= up_wdata[3:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h8)) begin
up_usr_datatype_be <= up_wdata[25];
up_usr_datatype_signed <= up_wdata[24];
up_usr_datatype_shift <= up_wdata[23:16];
up_usr_datatype_total_bits <= up_wdata[15:8];
up_usr_datatype_bits <= up_wdata[7:0];
end
if ((up_wr_s == 1'b1) && (up_addr[3:0] == 4'h9)) begin
up_usr_interpolation_m <= up_wdata[31:16];
up_usr_interpolation_n <= up_wdata[15:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[3:0])
4'h0: up_rdata <= {28'd0, up_dac_dds_scale_1};
4'h1: up_rdata <= {up_dac_dds_init_1, up_dac_dds_incr_1};
4'h2: up_rdata <= {28'd0, up_dac_dds_scale_2};
4'h3: up_rdata <= {up_dac_dds_init_2, up_dac_dds_incr_2};
4'h4: up_rdata <= {up_dac_dds_patt_2, up_dac_dds_patt_1};
4'h5: up_rdata <= {30'd0, up_dac_lb_enb, up_dac_pn_enb};
4'h6: up_rdata <= {28'd0, up_dac_dds_sel};
4'h8: up_rdata <= {6'd0, dac_usr_datatype_be, dac_usr_datatype_signed,
dac_usr_datatype_shift, dac_usr_datatype_total_bits,
dac_usr_datatype_bits};
4'h9: up_rdata <= {dac_usr_interpolation_m, dac_usr_interpolation_n};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// dac control & status
up_xfer_cntrl #(.DATA_WIDTH(110)) i_dac_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_dac_dds_scale_1,
up_dac_dds_init_1,
up_dac_dds_incr_1,
up_dac_dds_scale_2,
up_dac_dds_init_2,
up_dac_dds_incr_2,
up_dac_dds_patt_1,
up_dac_dds_patt_2,
up_dac_lb_enb,
up_dac_pn_enb,
up_dac_dds_sel}),
.d_rst (dac_rst),
.d_clk (dac_clk),
.d_data_cntrl ({ dac_dds_scale_1,
dac_dds_init_1,
dac_dds_incr_1,
dac_dds_scale_2,
dac_dds_init_2,
dac_dds_incr_2,
dac_dds_patt_1,
dac_dds_patt_2,
dac_lb_enb,
dac_pn_enb,
dac_dds_sel}));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,381 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_dac_common (
// mmcm reset
mmcm_rst,
// dac interface
dac_clk,
dac_rst,
dac_enable,
dac_frame,
dac_par_type,
dac_par_enb,
dac_r1_mode,
dac_datafmt,
dac_datasel,
dac_datarate,
dac_status,
dac_status_ovf,
dac_status_unf,
dac_clk_ratio,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked,
// user channel control
up_usr_chanmax,
dac_usr_chanmax,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00040062;
parameter PCORE_ID = 0;
// mmcm reset
output mmcm_rst;
// dac interface
input dac_clk;
output dac_rst;
output dac_enable;
output dac_frame;
output dac_par_type;
output dac_par_enb;
output dac_r1_mode;
output dac_datafmt;
output [ 3:0] dac_datasel;
output [ 7:0] dac_datarate;
input dac_status;
input dac_status_ovf;
input dac_status_unf;
input [31:0] dac_clk_ratio;
// drp interface
input drp_clk;
output drp_rst;
output drp_sel;
output drp_wr;
output [11:0] drp_addr;
output [15:0] drp_wdata;
input [15:0] drp_rdata;
input drp_ready;
input drp_locked;
// user channel control
output [ 7:0] up_usr_chanmax;
input [ 7:0] dac_usr_chanmax;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_mmcm_resetn = 'd0;
reg up_resetn = 'd0;
reg up_dac_enable = 'd0;
reg up_dac_par_type = 'd0;
reg up_dac_par_enb = 'd0;
reg up_dac_r1_mode = 'd0;
reg up_dac_datafmt = 'd0;
reg [ 3:0] up_dac_datasel = 'd0;
reg [ 7:0] up_dac_datarate = 'd0;
reg up_dac_frame = 'd0;
reg up_drp_sel_t = 'd0;
reg up_drp_rwn = 'd0;
reg [11:0] up_drp_addr = 'd0;
reg [15:0] up_drp_wdata = 'd0;
reg up_status_ovf = 'd0;
reg up_status_unf = 'd0;
reg [ 7:0] up_usr_chanmax = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
reg dac_frame_d = 'd0;
reg dac_frame_2d = 'd0;
reg dac_frame = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_mmcm_preset_s;
wire up_status_s;
wire up_status_ovf_s;
wire up_status_unf_s;
wire dac_frame_s;
wire [31:0] up_dac_clk_count_s;
wire [15:0] up_drp_rdata_s;
wire up_drp_status_s;
wire up_drp_locked_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h10) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
assign up_mmcm_preset_s = ~up_mmcm_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_mmcm_resetn <= 'd0;
up_resetn <= 'd0;
up_dac_enable <= 'd0;
up_dac_par_type <= 'd0;
up_dac_par_enb <= 'd0;
up_dac_r1_mode <= 'd0;
up_dac_datafmt <= 'd0;
up_dac_datasel <= 'd0;
up_dac_datarate <= 'd0;
up_dac_frame <= 'd0;
up_drp_sel_t <= 'd0;
up_drp_rwn <= 'd0;
up_drp_addr <= 'd0;
up_drp_wdata <= 'd0;
up_status_ovf <= 'd0;
up_status_ovf <= 'd0;
up_usr_chanmax <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h10)) begin
up_mmcm_resetn <= up_wdata[1];
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h11)) begin
up_dac_enable <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h12)) begin
up_dac_par_type <= up_wdata[7];
up_dac_par_enb <= up_wdata[6];
up_dac_r1_mode <= up_wdata[5];
up_dac_datafmt <= up_wdata[4];
up_dac_datasel <= up_wdata[3:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h13)) begin
up_dac_datarate <= up_wdata[7:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h14)) begin
up_dac_frame <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1c)) begin
up_drp_sel_t <= ~up_drp_sel_t;
up_drp_rwn <= up_wdata[28];
up_drp_addr <= up_wdata[27:16];
up_drp_wdata <= up_wdata[15:0];
end
if (up_status_ovf_s == 1'b1) begin
up_status_ovf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_status_ovf <= up_status_ovf & ~up_wdata[1];
end
if (up_status_unf_s == 1'b1) begin
up_status_unf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h22)) begin
up_status_unf <= up_status_unf & ~up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h28)) begin
up_usr_chanmax <= up_wdata[7:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h10: up_rdata <= {30'd0, up_mmcm_resetn, up_resetn};
8'h11: up_rdata <= {31'd0, up_dac_enable};
8'h12: up_rdata <= {24'd0, up_dac_par_type, up_dac_par_enb, up_dac_r1_mode,
up_dac_datafmt, up_dac_datasel};
8'h13: up_rdata <= {24'd0, up_dac_datarate};
8'h14: up_rdata <= {31'd0, up_dac_frame};
8'h15: up_rdata <= up_dac_clk_count_s;
8'h16: up_rdata <= dac_clk_ratio;
8'h17: up_rdata <= {31'd0, up_status_s};
8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata};
8'h1d: up_rdata <= {14'd0, up_drp_locked_s, up_drp_status_s, up_drp_rdata_s};
8'h22: up_rdata <= {30'd0, up_status_ovf, up_status_unf};
8'h28: up_rdata <= {24'd0, dac_usr_chanmax};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_mmcm_rst_reg (.preset(up_mmcm_preset_s), .clk(drp_clk), .rst(mmcm_rst));
ad_rst i_dac_rst_reg (.preset(up_preset_s), .clk(dac_clk), .rst(dac_rst));
ad_rst i_drp_rst_reg (.preset(up_preset_s), .clk(drp_clk), .rst(drp_rst));
// dac control & status
up_xfer_cntrl #(.DATA_WIDTH(18)) i_dac_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_dac_enable,
up_dac_frame,
up_dac_par_type,
up_dac_par_enb,
up_dac_r1_mode,
up_dac_datafmt,
up_dac_datasel,
up_dac_datarate}),
.d_rst (dac_rst),
.d_clk (dac_clk),
.d_data_cntrl ({ dac_enable,
dac_frame_s,
dac_par_type,
dac_par_enb,
dac_r1_mode,
dac_datafmt,
dac_datasel,
dac_datarate}));
up_xfer_status #(.DATA_WIDTH(3)) i_dac_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_status_s,
up_status_ovf_s,
up_status_unf_s}),
.d_rst (dac_rst),
.d_clk (dac_clk),
.d_data_status ({ dac_status,
dac_status_ovf,
dac_status_unf}));
// frame needs to be a pulse
always @(posedge dac_clk) begin
dac_frame_d <= dac_frame_s;
dac_frame_2d <= dac_frame_d;
dac_frame <= dac_frame_d & ~dac_frame_2d;
end
// dac clock monitor
up_clock_mon i_dac_clock_mon (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_d_count (up_dac_clk_count_s),
.d_rst (dac_rst),
.d_clk (dac_clk));
// drp control & status
up_drp_cntrl i_drp_cntrl (
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel),
.drp_wr (drp_wr),
.drp_addr (drp_addr),
.drp_wdata (drp_wdata),
.drp_rdata (drp_rdata),
.drp_ready (drp_ready),
.drp_locked (drp_locked),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_drp_sel_t (up_drp_sel_t),
.up_drp_rwn (up_drp_rwn),
.up_drp_addr (up_drp_addr),
.up_drp_wdata (up_drp_wdata),
.up_drp_rdata (up_drp_rdata_s),
.up_drp_status (up_drp_status_s),
.up_drp_locked (up_drp_locked_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,174 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_delay_cntrl (
// delay interface
delay_clk,
delay_rst,
delay_sel,
delay_rwn,
delay_addr,
delay_wdata,
delay_rdata,
delay_ack_t,
delay_locked,
// processor interface
up_rstn,
up_clk,
up_delay_sel,
up_delay_rwn,
up_delay_addr,
up_delay_wdata,
up_delay_rdata,
up_delay_status,
up_delay_locked);
// delay interface
input delay_clk;
input delay_rst;
output delay_sel;
output delay_rwn;
output [ 7:0] delay_addr;
output [ 4:0] delay_wdata;
input [ 4:0] delay_rdata;
input delay_ack_t;
input delay_locked;
// processor interface
input up_rstn;
input up_clk;
input up_delay_sel;
input up_delay_rwn;
input [ 7:0] up_delay_addr;
input [ 4:0] up_delay_wdata;
output [ 4:0] up_delay_rdata;
output up_delay_status;
output up_delay_locked;
// internal registers
reg delay_sel_m1 = 'd0;
reg delay_sel_m2 = 'd0;
reg delay_sel_m3 = 'd0;
reg delay_sel = 'd0;
reg delay_rwn = 'd0;
reg [ 7:0] delay_addr = 'd0;
reg [ 4:0] delay_wdata = 'd0;
reg up_delay_locked_m1 = 'd0;
reg up_delay_locked = 'd0;
reg up_delay_ack_t_m1 = 'd0;
reg up_delay_ack_t_m2 = 'd0;
reg up_delay_ack_t_m3 = 'd0;
reg up_delay_sel_d = 'd0;
reg up_delay_status = 'd0;
reg [ 4:0] up_delay_rdata = 'd0;
// internal signals
wire up_delay_ack_t_s;
wire up_delay_sel_s;
// delay control transfer
always @(posedge delay_clk) begin
if (delay_rst == 1'b1) begin
delay_sel_m1 <= 'd0;
delay_sel_m2 <= 'd0;
delay_sel_m3 <= 'd0;
end else begin
delay_sel_m1 <= up_delay_sel;
delay_sel_m2 <= delay_sel_m1;
delay_sel_m3 <= delay_sel_m2;
end
end
always @(posedge delay_clk) begin
delay_sel <= delay_sel_m2 & ~delay_sel_m3;
if ((delay_sel_m2 == 1'b1) && (delay_sel_m3 == 1'b0)) begin
delay_rwn <= up_delay_rwn;
delay_addr <= up_delay_addr;
delay_wdata <= up_delay_wdata;
end
end
// delay status transfer
assign up_delay_ack_t_s = up_delay_ack_t_m3 ^ up_delay_ack_t_m2;
assign up_delay_sel_s = up_delay_sel & ~up_delay_sel_d;
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_delay_locked_m1 <= 'd0;
up_delay_locked <= 'd0;
up_delay_ack_t_m1 <= 'd0;
up_delay_ack_t_m2 <= 'd0;
up_delay_ack_t_m3 <= 'd0;
up_delay_sel_d <= 'd0;
up_delay_status <= 'd0;
up_delay_rdata <= 'd0;
end else begin
up_delay_locked_m1 <= delay_locked;
up_delay_locked <= up_delay_locked_m1;
up_delay_ack_t_m1 <= delay_ack_t;
up_delay_ack_t_m2 <= up_delay_ack_t_m1;
up_delay_ack_t_m3 <= up_delay_ack_t_m2;
up_delay_sel_d <= up_delay_sel;
if (up_delay_ack_t_s == 1'b1) begin
up_delay_status <= 1'b0;
end else if (up_delay_sel_s == 1'b1) begin
up_delay_status <= 1'b1;
end
if (up_delay_ack_t_s == 1'b1) begin
up_delay_rdata <= delay_rdata;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,194 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_drp_cntrl (
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_locked,
// processor interface
up_rstn,
up_clk,
up_drp_sel_t,
up_drp_rwn,
up_drp_addr,
up_drp_wdata,
up_drp_rdata,
up_drp_status,
up_drp_locked);
// drp interface
input drp_clk;
input drp_rst;
output drp_sel;
output drp_wr;
output [11:0] drp_addr;
output [15:0] drp_wdata;
input [15:0] drp_rdata;
input drp_ready;
input drp_locked;
// processor interface
input up_rstn;
input up_clk;
input up_drp_sel_t;
input up_drp_rwn;
input [11:0] up_drp_addr;
input [15:0] up_drp_wdata;
output [15:0] up_drp_rdata;
output up_drp_status;
output up_drp_locked;
// internal registers
reg drp_sel_t_m1 = 'd0;
reg drp_sel_t_m2 = 'd0;
reg drp_sel_t_m3 = 'd0;
reg drp_sel = 'd0;
reg drp_wr = 'd0;
reg [11:0] drp_addr = 'd0;
reg [15:0] drp_wdata = 'd0;
reg drp_ready_int = 'd0;
reg [15:0] drp_rdata_int = 'd0;
reg drp_ack_t = 'd0;
reg up_drp_locked_m1 = 'd0;
reg up_drp_locked = 'd0;
reg up_drp_ack_t_m1 = 'd0;
reg up_drp_ack_t_m2 = 'd0;
reg up_drp_ack_t_m3 = 'd0;
reg up_drp_sel_t_d = 'd0;
reg up_drp_status = 'd0;
reg [15:0] up_drp_rdata = 'd0;
// internal signals
wire drp_sel_t_s;
wire up_drp_ack_t_s;
wire up_drp_sel_t_s;
// drp control and status
assign drp_sel_t_s = drp_sel_t_m2 ^ drp_sel_t_m3;
always @(posedge drp_clk) begin
if (drp_rst == 1'b1) begin
drp_sel_t_m1 <= 'd0;
drp_sel_t_m2 <= 'd0;
drp_sel_t_m3 <= 'd0;
end else begin
drp_sel_t_m1 <= up_drp_sel_t;
drp_sel_t_m2 <= drp_sel_t_m1;
drp_sel_t_m3 <= drp_sel_t_m2;
end
end
always @(posedge drp_clk) begin
if (drp_sel_t_s == 1'b1) begin
drp_sel <= 1'b1;
drp_wr <= ~up_drp_rwn;
drp_addr <= up_drp_addr;
drp_wdata <= up_drp_wdata;
end else begin
drp_sel <= 1'b0;
drp_wr <= 1'b0;
drp_addr <= 12'd0;
drp_wdata <= 16'd0;
end
end
always @(posedge drp_clk) begin
drp_ready_int <= drp_ready;
if ((drp_ready_int == 1'b0) && (drp_ready == 1'b1)) begin
drp_rdata_int <= drp_rdata;
drp_ack_t <= ~drp_ack_t;
end
end
// drp status transfer
assign up_drp_ack_t_s = up_drp_ack_t_m3 ^ up_drp_ack_t_m2;
assign up_drp_sel_t_s = up_drp_sel_t ^ up_drp_sel_t_d;
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_drp_locked_m1 <= 'd0;
up_drp_locked <= 'd0;
up_drp_ack_t_m1 <= 'd0;
up_drp_ack_t_m2 <= 'd0;
up_drp_ack_t_m3 <= 'd0;
up_drp_sel_t_d <= 'd0;
up_drp_status <= 'd0;
up_drp_rdata <= 'd0;
end else begin
up_drp_locked_m1 <= drp_locked;
up_drp_locked <= up_drp_locked_m1;
up_drp_ack_t_m1 <= drp_ack_t;
up_drp_ack_t_m2 <= up_drp_ack_t_m1;
up_drp_ack_t_m3 <= up_drp_ack_t_m2;
up_drp_sel_t_d <= up_drp_sel_t;
if (up_drp_ack_t_s == 1'b1) begin
up_drp_status <= 1'b0;
end else if (up_drp_sel_t_s == 1'b1) begin
up_drp_status <= 1'b1;
end
if (up_drp_ack_t_s == 1'b1) begin
up_drp_rdata <= drp_rdata_int;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

793
library/common/up_gt.v Normal file
View File

@ -0,0 +1,793 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_gt (
// gt interface
gt_pll_rst,
gt_rx_rst,
gt_tx_rst,
up_cpll_pd,
up_rx_sys_clk_sel,
up_rx_out_clk_sel,
up_tx_sys_clk_sel,
up_tx_out_clk_sel,
// receive interface
rx_clk,
rx_rst,
rx_ext_sysref,
rx_sysref,
rx_ip_sync,
rx_sync,
rx_rst_done,
rx_pll_locked,
rx_error,
// transmit interface
tx_clk,
tx_rst,
tx_ext_sysref,
tx_sysref,
tx_sync,
tx_ip_sync,
tx_rst_done,
tx_pll_locked,
tx_error,
// drp interface
drp_clk,
drp_rst,
drp_sel,
drp_wr,
drp_addr,
drp_wdata,
drp_rdata,
drp_ready,
drp_lanesel,
drp_rx_rate,
// es interface
es_sel,
es_wr,
es_addr,
es_wdata,
es_rdata,
es_ready,
es_start,
es_stop,
es_init,
es_prescale,
es_voffset_step,
es_voffset_max,
es_voffset_min,
es_hoffset_max,
es_hoffset_min,
es_hoffset_step,
es_start_addr,
es_sdata0,
es_sdata1,
es_sdata2,
es_sdata3,
es_sdata4,
es_qdata0,
es_qdata1,
es_qdata2,
es_qdata3,
es_qdata4,
es_dmaerr,
es_status,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00040062;
parameter PCORE_ID = 0;
// gt interface
output gt_pll_rst;
output gt_rx_rst;
output gt_tx_rst;
output up_cpll_pd;
output [ 1:0] up_rx_sys_clk_sel;
output [ 2:0] up_rx_out_clk_sel;
output [ 1:0] up_tx_sys_clk_sel;
output [ 2:0] up_tx_out_clk_sel;
// receive interface
input rx_clk;
output rx_rst;
input rx_ext_sysref;
output rx_sysref;
input rx_ip_sync;
output rx_sync;
input [ 7:0] rx_rst_done;
input [ 7:0] rx_pll_locked;
input rx_error;
// transmit interface
input tx_clk;
output tx_rst;
input tx_ext_sysref;
output tx_sysref;
input tx_sync;
output tx_ip_sync;
input [ 7:0] tx_rst_done;
input [ 7:0] tx_pll_locked;
input tx_error;
// drp interface
input drp_clk;
output drp_rst;
output drp_sel;
output drp_wr;
output [11:0] drp_addr;
output [15:0] drp_wdata;
input [15:0] drp_rdata;
input drp_ready;
output [ 7:0] drp_lanesel;
input [ 7:0] drp_rx_rate;
// es interface
input es_sel;
input es_wr;
input [11:0] es_addr;
input [15:0] es_wdata;
output [15:0] es_rdata;
output es_ready;
output es_start;
output es_stop;
output es_init;
output [ 4:0] es_prescale;
output [ 7:0] es_voffset_step;
output [ 7:0] es_voffset_max;
output [ 7:0] es_voffset_min;
output [11:0] es_hoffset_max;
output [11:0] es_hoffset_min;
output [11:0] es_hoffset_step;
output [31:0] es_start_addr;
output [15:0] es_sdata0;
output [15:0] es_sdata1;
output [15:0] es_sdata2;
output [15:0] es_sdata3;
output [15:0] es_sdata4;
output [15:0] es_qdata0;
output [15:0] es_qdata1;
output [15:0] es_qdata2;
output [15:0] es_qdata3;
output [15:0] es_qdata4;
input es_dmaerr;
input es_status;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_cpll_pd = 'd0;
reg up_drp_resetn = 'd0;
reg up_gt_pll_resetn = 'd0;
reg up_gt_rx_resetn = 'd0;
reg up_rx_resetn = 'd0;
reg [ 1:0] up_rx_sys_clk_sel = 'd0;
reg [ 2:0] up_rx_out_clk_sel = 'd0;
reg up_rx_sysref_sel = 'd0;
reg up_rx_sysref = 'd0;
reg up_rx_sync = 'd0;
reg up_gt_tx_resetn = 'd0;
reg up_tx_resetn = 'd0;
reg [ 1:0] up_tx_sys_clk_sel = 'd0;
reg [ 2:0] up_tx_out_clk_sel = 'd0;
reg up_tx_sysref_sel = 'd0;
reg up_tx_sysref = 'd0;
reg up_tx_sync = 'd0;
reg [ 7:0] up_lanesel = 'd0;
reg up_drp_sel_t = 'd0;
reg up_drp_rwn = 'd0;
reg [11:0] up_drp_addr = 'd0;
reg [15:0] up_drp_wdata = 'd0;
reg up_es_init = 'd0;
reg up_es_stop = 'd0;
reg up_es_start = 'd0;
reg [ 4:0] up_es_prescale = 'd0;
reg [ 7:0] up_es_voffset_step = 'd0;
reg [ 7:0] up_es_voffset_max = 'd0;
reg [ 7:0] up_es_voffset_min = 'd0;
reg [11:0] up_es_hoffset_max = 'd0;
reg [11:0] up_es_hoffset_min = 'd0;
reg [11:0] up_es_hoffset_step = 'd0;
reg [31:0] up_es_start_addr = 'd0;
reg [15:0] up_es_sdata1 = 'd0;
reg [15:0] up_es_sdata0 = 'd0;
reg [15:0] up_es_sdata3 = 'd0;
reg [15:0] up_es_sdata2 = 'd0;
reg [15:0] up_es_sdata4 = 'd0;
reg [15:0] up_es_qdata1 = 'd0;
reg [15:0] up_es_qdata0 = 'd0;
reg [15:0] up_es_qdata3 = 'd0;
reg [15:0] up_es_qdata2 = 'd0;
reg [15:0] up_es_qdata4 = 'd0;
reg up_es_dmaerr = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
reg rx_sysref_m1 = 'd0;
reg rx_sysref_m2 = 'd0;
reg rx_sysref_m3 = 'd0;
reg rx_sysref = 'd0;
reg rx_sync_m1 = 'd0;
reg rx_sync_m2 = 'd0;
reg rx_sync = 'd0;
reg tx_sysref_m1 = 'd0;
reg tx_sysref_m2 = 'd0;
reg tx_sysref_m3 = 'd0;
reg tx_sysref = 'd0;
reg tx_ip_sync_m1 = 'd0;
reg tx_ip_sync_m2 = 'd0;
reg tx_ip_sync = 'd0;
reg up_rx_status_m1 = 'd0;
reg up_rx_status = 'd0;
reg up_tx_status_m1 = 'd0;
reg up_tx_status = 'd0;
reg drp_sel = 'd0;
reg drp_wr = 'd0;
reg [11:0] drp_addr = 'd0;
reg [15:0] drp_wdata = 'd0;
reg [15:0] es_rdata = 'd0;
reg es_ready = 'd0;
reg [15:0] drp_rdata_int = 'd0;
reg drp_ready_int = 'd0;
reg es_start_m1 = 'd0;
reg es_start_m2 = 'd0;
reg es_start_m3 = 'd0;
reg es_stop_m1 = 'd0;
reg es_stop_m2 = 'd0;
reg es_stop_m3 = 'd0;
reg es_start = 'd0;
reg es_stop = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire rx_rst_done_s;
wire rx_pll_locked_s;
wire tx_rst_done_s;
wire tx_pll_locked_s;
wire up_drp_preset_s;
wire up_gt_pll_preset_s;
wire up_gt_rx_preset_s;
wire up_gt_tx_preset_s;
wire up_rx_preset_s;
wire up_tx_preset_s;
wire rx_sysref_s;
wire tx_sysref_s;
wire drp_sel_s;
wire drp_wr_s;
wire [11:0] drp_addr_s;
wire [15:0] drp_wdata_s;
wire [15:0] up_drp_rdata_s;
wire up_drp_status_s;
wire [ 7:0] up_drp_rx_rate_s;
wire up_es_dmaerr_s;
wire up_es_status_s;
// decode block select
assign up_sel_s = (up_addr[13:8] == 6'h00) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
// status inputs
assign rx_rst_done_s = & rx_rst_done;
assign rx_pll_locked_s = & rx_pll_locked;
assign tx_rst_done_s = & tx_rst_done;
assign tx_pll_locked_s = & tx_pll_locked;
// resets
assign up_drp_preset_s = ~up_drp_resetn;
assign up_gt_pll_preset_s = ~up_gt_pll_resetn;
assign up_gt_rx_preset_s = ~(up_gt_pll_resetn & up_gt_rx_resetn & rx_pll_locked_s);
assign up_gt_tx_preset_s = ~(up_gt_pll_resetn & up_gt_tx_resetn & tx_pll_locked_s);
assign up_rx_preset_s = ~(up_gt_pll_resetn & up_gt_rx_resetn & up_rx_resetn & rx_pll_locked_s & rx_rst_done_s);
assign up_tx_preset_s = ~(up_gt_pll_resetn & up_gt_tx_resetn & up_tx_resetn & tx_pll_locked_s & tx_rst_done_s);
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_cpll_pd <= 'd1;
up_drp_resetn <= 'd0;
up_gt_pll_resetn <= 'd0;
up_gt_rx_resetn <= 'd0;
up_rx_resetn <= 'd0;
up_rx_sys_clk_sel <= 2'b11;
up_rx_out_clk_sel <= 3'b010;
up_rx_sysref_sel <= 'd0;
up_rx_sysref <= 'd0;
up_rx_sync <= 'd0;
up_gt_tx_resetn <= 'd0;
up_tx_resetn <= 'd0;
up_tx_sys_clk_sel <= 2'b11;
up_tx_out_clk_sel <= 3'b010;
up_tx_sysref_sel <= 'd0;
up_tx_sysref <= 'd0;
up_tx_sync <= 'd0;
up_lanesel <= 'd0;
up_drp_sel_t <= 'd0;
up_drp_rwn <= 'd0;
up_drp_addr <= 'd0;
up_drp_wdata <= 'd0;
up_es_init <= 'd0;
up_es_stop <= 'd0;
up_es_start <= 'd0;
up_es_prescale <= 'd0;
up_es_voffset_step <= 'd0;
up_es_voffset_max <= 'd0;
up_es_voffset_min <= 'd0;
up_es_hoffset_max <= 'd0;
up_es_hoffset_min <= 'd0;
up_es_hoffset_step <= 'd0;
up_es_start_addr <= 'd0;
up_es_sdata1 <= 'd0;
up_es_sdata0 <= 'd0;
up_es_sdata3 <= 'd0;
up_es_sdata2 <= 'd0;
up_es_sdata4 <= 'd0;
up_es_qdata1 <= 'd0;
up_es_qdata0 <= 'd0;
up_es_qdata3 <= 'd0;
up_es_qdata2 <= 'd0;
up_es_qdata4 <= 'd0;
up_es_dmaerr <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h02)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h04)) begin
up_cpll_pd <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h05)) begin
up_drp_resetn <= up_wdata[1];
up_gt_pll_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h08)) begin
up_gt_rx_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h09)) begin
up_rx_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h0a)) begin
up_rx_sys_clk_sel <= up_wdata[5:4];
up_rx_out_clk_sel <= up_wdata[2:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h0b)) begin
up_rx_sysref_sel <= up_wdata[1];
up_rx_sysref <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h0c)) begin
up_rx_sync <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h18)) begin
up_gt_tx_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h19)) begin
up_tx_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1a)) begin
up_tx_sys_clk_sel <= up_wdata[5:4];
up_tx_out_clk_sel <= up_wdata[2:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1b)) begin
up_tx_sysref_sel <= up_wdata[1];
up_tx_sysref <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h1c)) begin
up_tx_sync <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h23)) begin
up_lanesel <= up_wdata[7:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h24)) begin
up_drp_sel_t <= ~up_drp_sel_t;
up_drp_rwn <= up_wdata[28];
up_drp_addr <= up_wdata[27:16];
up_drp_wdata <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h28)) begin
up_es_init <= up_wdata[2];
up_es_stop <= up_wdata[1];
up_es_start <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h29)) begin
up_es_prescale <= up_wdata[4:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2a)) begin
up_es_voffset_step <= up_wdata[23:16];
up_es_voffset_max <= up_wdata[15:8];
up_es_voffset_min <= up_wdata[7:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2b)) begin
up_es_hoffset_max <= up_wdata[27:16];
up_es_hoffset_min <= up_wdata[11:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2c)) begin
up_es_hoffset_step <= up_wdata[11:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2d)) begin
up_es_start_addr <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2e)) begin
up_es_sdata1 <= up_wdata[31:16];
up_es_sdata0 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h2f)) begin
up_es_sdata3 <= up_wdata[31:16];
up_es_sdata2 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h30)) begin
up_es_sdata4 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h31)) begin
up_es_qdata1 <= up_wdata[31:16];
up_es_qdata0 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h32)) begin
up_es_qdata3 <= up_wdata[31:16];
up_es_qdata2 <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h33)) begin
up_es_qdata4 <= up_wdata[15:0];
end
if (up_es_dmaerr_s == 1'b1) begin
up_es_dmaerr <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[7:0] == 8'h38)) begin
up_es_dmaerr <= up_es_dmaerr & ~up_wdata[1];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[7:0])
8'h00: up_rdata <= PCORE_VERSION;
8'h01: up_rdata <= PCORE_ID;
8'h02: up_rdata <= up_scratch;
8'h04: up_rdata <= {31'd0, up_cpll_pd};
8'h05: up_rdata <= {30'd0, up_drp_resetn, up_gt_pll_resetn};
8'h08: up_rdata <= {31'd0, up_gt_rx_resetn};
8'h09: up_rdata <= {31'd0, up_rx_resetn};
8'h0a: up_rdata <= {24'd0, 2'd0, up_rx_sys_clk_sel, 1'd0, up_rx_out_clk_sel};
8'h0b: up_rdata <= {30'd0, up_rx_sysref_sel, up_rx_sysref};
8'h0c: up_rdata <= {31'd0, up_rx_sync};
8'h0d: up_rdata <= {15'd0, up_rx_status, rx_rst_done, rx_pll_locked};
8'h18: up_rdata <= {31'd0, up_gt_tx_resetn};
8'h19: up_rdata <= {31'd0, up_tx_resetn};
8'h1a: up_rdata <= {24'd0, 2'd0, up_tx_sys_clk_sel, 1'd0, up_tx_out_clk_sel};
8'h1b: up_rdata <= {30'd0, up_tx_sysref_sel, up_tx_sysref};
8'h1c: up_rdata <= {31'd0, up_tx_sync};
8'h1d: up_rdata <= {15'd0, up_tx_status, tx_rst_done, tx_pll_locked};
8'h23: up_rdata <= {24'd0, up_lanesel};
8'h24: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata};
8'h25: up_rdata <= {15'd0, up_drp_status_s, up_drp_rdata_s};
8'h28: up_rdata <= {29'd0, up_es_init, up_es_stop, up_es_start};
8'h29: up_rdata <= {27'd0, up_es_prescale};
8'h2a: up_rdata <= {8'd0, up_es_voffset_step, up_es_voffset_max, up_es_voffset_min};
8'h2b: up_rdata <= {4'd0, up_es_hoffset_max, 4'd0, up_es_hoffset_min};
8'h2c: up_rdata <= {20'd0, up_es_hoffset_step};
8'h2d: up_rdata <= up_es_start_addr;
8'h2e: up_rdata <= {up_es_sdata1, up_es_sdata0};
8'h2f: up_rdata <= {up_es_sdata3, up_es_sdata2};
8'h30: up_rdata <= up_es_sdata4;
8'h31: up_rdata <= {up_es_qdata1, up_es_qdata0};
8'h32: up_rdata <= {up_es_qdata3, up_es_qdata2};
8'h33: up_rdata <= up_es_qdata4;
8'h38: up_rdata <= {30'd0, up_es_dmaerr, up_es_status_s};
8'h39: up_rdata <= {24'd0, up_drp_rx_rate_s};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_drp_rst_reg (.preset(up_drp_preset_s), .clk(drp_clk), .rst(drp_rst));
ad_rst i_gt_pll_rst_reg (.preset(up_gt_pll_preset_s), .clk(drp_clk), .rst(gt_pll_rst));
ad_rst i_gt_rx_rst_reg (.preset(up_gt_rx_preset_s), .clk(rx_clk), .rst(gt_rx_rst));
ad_rst i_gt_tx_rst_reg (.preset(up_gt_tx_preset_s), .clk(tx_clk), .rst(gt_tx_rst));
ad_rst i_rx_rst_reg (.preset(up_rx_preset_s), .clk(rx_clk), .rst(rx_rst));
ad_rst i_tx_rst_reg (.preset(up_tx_preset_s), .clk(tx_clk), .rst(tx_rst));
// rx sysref & sync
assign rx_sysref_s = (up_rx_sysref_sel == 1'b1) ? rx_ext_sysref : up_rx_sysref;
always @(posedge rx_clk) begin
if (rx_rst == 1'b1) begin
rx_sysref_m1 <= 'd0;
rx_sysref_m2 <= 'd0;
rx_sysref_m3 <= 'd0;
rx_sysref <= 'd0;
rx_sync_m1 <= 'd0;
rx_sync_m2 <= 'd0;
rx_sync <= 'd0;
end else begin
rx_sysref_m1 <= rx_sysref_s;
rx_sysref_m2 <= rx_sysref_m1;
rx_sysref_m3 <= rx_sysref_m2;
rx_sysref <= rx_sysref_m2 & ~rx_sysref_m3;
rx_sync_m1 <= up_rx_sync & rx_ip_sync;
rx_sync_m2 <= rx_sync_m1;
rx_sync <= rx_sync_m2;
end
end
// tx sysref & sync
assign tx_sysref_s = (up_tx_sysref_sel == 1'b1) ? tx_ext_sysref : up_tx_sysref;
always @(posedge tx_clk) begin
if (tx_rst == 1'b1) begin
tx_sysref_m1 <= 'd0;
tx_sysref_m2 <= 'd0;
tx_sysref_m3 <= 'd0;
tx_sysref <= 'd0;
tx_ip_sync_m1 <= 'd0;
tx_ip_sync_m2 <= 'd0;
tx_ip_sync <= 'd0;
end else begin
tx_sysref_m1 <= tx_sysref_s;
tx_sysref_m2 <= tx_sysref_m1;
tx_sysref_m3 <= tx_sysref_m2;
tx_sysref <= tx_sysref_m2 & ~tx_sysref_m3;
tx_ip_sync_m1 <= up_tx_sync & tx_sync;
tx_ip_sync_m2 <= tx_ip_sync_m1;
tx_ip_sync <= tx_ip_sync_m2;
end
end
// status
always @(posedge up_clk) begin
if (up_rstn == 0) begin
up_rx_status_m1 <= 'd0;
up_rx_status <= 'd0;
up_tx_status_m1 <= 'd0;
up_tx_status <= 'd0;
end else begin
up_rx_status_m1 <= rx_sync & ~rx_error;
up_rx_status <= up_rx_status_m1;
up_tx_status_m1 <= tx_ip_sync & ~tx_error;
up_tx_status <= up_tx_status_m1;
end
end
// drp mux (es runs on drp clock)
always @(posedge drp_clk) begin
if (es_status == 1'b1) begin
drp_sel <= es_sel;
drp_wr <= es_wr;
drp_addr <= es_addr;
drp_wdata <= es_wdata;
es_rdata <= drp_rdata;
es_ready <= drp_ready;
drp_rdata_int <= 16'd0;
drp_ready_int <= 1'd0;
end else begin
drp_sel <= drp_sel_s;
drp_wr <= drp_wr_s;
drp_addr <= drp_addr_s;
drp_wdata <= drp_wdata_s;
es_rdata <= 16'd0;
es_ready <= 1'd0;
drp_rdata_int <= drp_rdata;
drp_ready_int <= drp_ready;
end
end
// drp control & status
up_drp_cntrl i_drp_cntrl (
.drp_clk (drp_clk),
.drp_rst (drp_rst),
.drp_sel (drp_sel_s),
.drp_wr (drp_wr_s),
.drp_addr (drp_addr_s),
.drp_wdata (drp_wdata_s),
.drp_rdata (drp_rdata_int),
.drp_ready (drp_ready_int),
.drp_locked (1'b0),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_drp_sel_t (up_drp_sel_t),
.up_drp_rwn (up_drp_rwn),
.up_drp_addr (up_drp_addr),
.up_drp_wdata (up_drp_wdata),
.up_drp_rdata (up_drp_rdata_s),
.up_drp_status (up_drp_status_s),
.up_drp_locked ());
// drp control xfer
up_xfer_cntrl #(.DATA_WIDTH(8)) i_drp_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl (up_lanesel),
.d_rst (drp_rst),
.d_clk (drp_clk),
.d_data_cntrl (drp_lanesel));
// drp status xfer
up_xfer_status #(.DATA_WIDTH(8)) i_drp_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status (up_drp_rx_rate_s),
.d_rst (drp_rst),
.d_clk (drp_clk),
.d_data_status (drp_rx_rate));
// es start & stop
always @(posedge drp_clk) begin
if (drp_rst == 1'b1) begin
es_start_m1 <= 'd0;
es_start_m2 <= 'd0;
es_start_m3 <= 'd0;
es_stop_m1 <= 'd0;
es_stop_m2 <= 'd0;
es_stop_m3 <= 'd0;
es_start <= 'd0;
es_stop <= 'd0;
end else begin
es_start_m1 <= up_es_start;
es_start_m2 <= es_start_m1;
es_start_m3 <= es_start_m2;
es_stop_m1 <= up_es_stop;
es_stop_m2 <= es_stop_m1;
es_stop_m3 <= es_stop_m2;
es_start <= es_start_m2 & ~es_start_m3;
es_stop <= es_stop_m2 & ~es_stop_m3;
end
end
// es control & status
up_xfer_cntrl #(.DATA_WIDTH(258)) i_es_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_es_init,
up_es_prescale,
up_es_voffset_step,
up_es_voffset_max,
up_es_voffset_min,
up_es_hoffset_max,
up_es_hoffset_min,
up_es_hoffset_step,
up_es_start_addr,
up_es_sdata1,
up_es_sdata0,
up_es_sdata3,
up_es_sdata2,
up_es_sdata4,
up_es_qdata1,
up_es_qdata0,
up_es_qdata3,
up_es_qdata2,
up_es_qdata4}),
.d_rst (drp_rst),
.d_clk (drp_clk),
.d_data_cntrl ({ es_init,
es_prescale,
es_voffset_step,
es_voffset_max,
es_voffset_min,
es_hoffset_max,
es_hoffset_min,
es_hoffset_step,
es_start_addr,
es_sdata1,
es_sdata0,
es_sdata3,
es_sdata2,
es_sdata4,
es_qdata1,
es_qdata0,
es_qdata3,
es_qdata2,
es_qdata4}));
// status
up_xfer_status #(.DATA_WIDTH(2)) i_es_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_es_dmaerr_s, up_es_status_s}),
.d_rst (drp_rst),
.d_clk (drp_clk),
.d_data_status ({es_dmaerr, es_status}));
endmodule
// ***************************************************************************
// ***************************************************************************

373
library/common/up_hdmi_tx.v Normal file
View File

@ -0,0 +1,373 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_hdmi_tx (
// hdmi interface
hdmi_clk,
hdmi_rst,
hdmi_full_range,
hdmi_csc_bypass,
hdmi_srcsel,
hdmi_const_rgb,
hdmi_hl_active,
hdmi_hl_width,
hdmi_hs_width,
hdmi_he_max,
hdmi_he_min,
hdmi_vf_active,
hdmi_vf_width,
hdmi_vs_width,
hdmi_ve_max,
hdmi_ve_min,
hdmi_status,
hdmi_tpm_oos,
hdmi_clk_ratio,
// vdma interface
vdma_clk,
vdma_rst,
vdma_ovf,
vdma_unf,
vdma_tpm_oos,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter PCORE_VERSION = 32'h00040062;
parameter PCORE_ID = 0;
// hdmi interface
input hdmi_clk;
output hdmi_rst;
output hdmi_full_range;
output hdmi_csc_bypass;
output [ 1:0] hdmi_srcsel;
output [23:0] hdmi_const_rgb;
output [15:0] hdmi_hl_active;
output [15:0] hdmi_hl_width;
output [15:0] hdmi_hs_width;
output [15:0] hdmi_he_max;
output [15:0] hdmi_he_min;
output [15:0] hdmi_vf_active;
output [15:0] hdmi_vf_width;
output [15:0] hdmi_vs_width;
output [15:0] hdmi_ve_max;
output [15:0] hdmi_ve_min;
input hdmi_status;
input hdmi_tpm_oos;
input [31:0] hdmi_clk_ratio;
// vdma interface
input vdma_clk;
output vdma_rst;
input vdma_ovf;
input vdma_unf;
input vdma_tpm_oos;
// bus interface
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
// internal registers
reg [31:0] up_scratch = 'd0;
reg up_resetn = 'd0;
reg up_full_range = 'd0;
reg up_csc_bypass = 'd0;
reg [ 1:0] up_srcsel = 'd1;
reg [23:0] up_const_rgb = 'd0;
reg up_vdma_ovf = 'd0;
reg up_vdma_unf = 'd0;
reg up_hdmi_tpm_oos = 'd0;
reg up_vdma_tpm_oos = 'd0;
reg [15:0] up_hl_active = 'd0;
reg [15:0] up_hl_width = 'd0;
reg [15:0] up_hs_width = 'd0;
reg [15:0] up_he_max = 'd0;
reg [15:0] up_he_min = 'd0;
reg [15:0] up_vf_active = 'd0;
reg [15:0] up_vf_width = 'd0;
reg [15:0] up_vs_width = 'd0;
reg [15:0] up_ve_max = 'd0;
reg [15:0] up_ve_min = 'd0;
reg up_ack = 'd0;
reg [31:0] up_rdata = 'd0;
// internal signals
wire up_sel_s;
wire up_wr_s;
wire up_preset_s;
wire up_hdmi_status_s;
wire up_hdmi_tpm_oos_s;
wire [31:0] up_hdmi_clk_count_s;
wire up_vdma_ovf_s;
wire up_vdma_unf_s;
wire up_vdma_tpm_oos_s;
// decode block select
assign up_sel_s = (up_addr[13:12] == 2'd0) ? up_sel : 1'b0;
assign up_wr_s = up_sel_s & up_wr;
assign up_preset_s = ~up_resetn;
// processor write interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_scratch <= 'd0;
up_resetn <= 'd0;
up_full_range <= 'd0;
up_csc_bypass <= 'd0;
up_srcsel <= 'd1;
up_const_rgb <= 'd0;
up_vdma_ovf <= 'd0;
up_vdma_unf <= 'd0;
up_hdmi_tpm_oos <= 'd0;
up_vdma_tpm_oos <= 'd0;
up_hl_active <= 'd0;
up_hl_width <= 'd0;
up_hs_width <= 'd0;
up_he_max <= 'd0;
up_he_min <= 'd0;
up_vf_active <= 'd0;
up_vf_width <= 'd0;
up_vs_width <= 'd0;
up_ve_max <= 'd0;
up_ve_min <= 'd0;
end else begin
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h002)) begin
up_scratch <= up_wdata;
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h010)) begin
up_resetn <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h011)) begin
up_full_range <= up_wdata[1];
up_csc_bypass <= up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h012)) begin
up_srcsel <= up_wdata[1:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h013)) begin
up_const_rgb <= up_wdata[23:0];
end
if (up_vdma_ovf_s == 1'b1) begin
up_vdma_ovf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h018)) begin
up_vdma_ovf <= up_vdma_ovf & ~up_wdata[1];
end
if (up_vdma_unf_s == 1'b1) begin
up_vdma_unf <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h018)) begin
up_vdma_unf <= up_vdma_unf & ~up_wdata[0];
end
if (up_hdmi_tpm_oos_s == 1'b1) begin
up_hdmi_tpm_oos <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h019)) begin
up_hdmi_tpm_oos <= up_hdmi_tpm_oos & ~up_wdata[1];
end
if (up_vdma_tpm_oos_s == 1'b1) begin
up_vdma_tpm_oos <= 1'b1;
end else if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h019)) begin
up_vdma_tpm_oos <= up_vdma_tpm_oos & ~up_wdata[0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h100)) begin
up_hl_active <= up_wdata[31:16];
up_hl_width <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h101)) begin
up_hs_width <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h102)) begin
up_he_max <= up_wdata[31:16];
up_he_min <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h110)) begin
up_vf_active <= up_wdata[31:16];
up_vf_width <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h111)) begin
up_vs_width <= up_wdata[15:0];
end
if ((up_wr_s == 1'b1) && (up_addr[11:0] == 12'h112)) begin
up_ve_max <= up_wdata[31:16];
up_ve_min <= up_wdata[15:0];
end
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_ack <= 'd0;
up_rdata <= 'd0;
end else begin
up_ack <= up_sel_s;
if (up_sel_s == 1'b1) begin
case (up_addr[11:0])
12'h000: up_rdata <= PCORE_VERSION;
12'h001: up_rdata <= PCORE_ID;
12'h002: up_rdata <= up_scratch;
12'h010: up_rdata <= {31'd0, up_resetn};
12'h011: up_rdata <= {30'd0, up_full_range, up_csc_bypass};
12'h012: up_rdata <= {30'd0, up_srcsel};
12'h013: up_rdata <= {8'd0, up_const_rgb};
12'h015: up_rdata <= up_hdmi_clk_count_s;
12'h016: up_rdata <= hdmi_clk_ratio;
12'h017: up_rdata <= {31'd0, up_hdmi_status_s};
12'h018: up_rdata <= {30'd0, up_vdma_ovf, up_vdma_unf};
12'h019: up_rdata <= {30'd0, up_hdmi_tpm_oos, up_vdma_tpm_oos};
12'h100: up_rdata <= {up_hl_active, up_hl_width};
12'h101: up_rdata <= {16'd0, up_hs_width};
12'h102: up_rdata <= {up_he_max, up_he_min};
12'h110: up_rdata <= {up_vf_active, up_vf_width};
12'h111: up_rdata <= {16'd0, up_vs_width};
12'h112: up_rdata <= {up_ve_max, up_ve_min};
default: up_rdata <= 0;
endcase
end else begin
up_rdata <= 32'd0;
end
end
end
// resets
ad_rst i_hdmi_rst_reg (.preset(up_preset_s), .clk(hdmi_clk), .rst(hdmi_rst));
ad_rst i_vdma_rst_reg (.preset(up_preset_s), .clk(vdma_clk), .rst(vdma_rst));
// hdmi control & status
up_xfer_cntrl #(.DATA_WIDTH(188)) i_hdmi_xfer_cntrl (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_cntrl ({ up_full_range,
up_csc_bypass,
up_srcsel,
up_const_rgb,
up_hl_active,
up_hl_width,
up_hs_width,
up_he_max,
up_he_min,
up_vf_active,
up_vf_width,
up_vs_width,
up_ve_max,
up_ve_min}),
.d_rst (hdmi_rst),
.d_clk (hdmi_clk),
.d_data_cntrl ({ hdmi_full_range,
hdmi_csc_bypass,
hdmi_srcsel,
hdmi_const_rgb,
hdmi_hl_active,
hdmi_hl_width,
hdmi_hs_width,
hdmi_he_max,
hdmi_he_min,
hdmi_vf_active,
hdmi_vf_width,
hdmi_vs_width,
hdmi_ve_max,
hdmi_ve_min}));
up_xfer_status #(.DATA_WIDTH(2)) i_hdmi_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_hdmi_status_s,
up_hdmi_tpm_oos_s}),
.d_rst (hdmi_rst),
.d_clk (hdmi_clk),
.d_data_status ({ hdmi_status,
hdmi_tpm_oos}));
// hdmi clock monitor
up_clock_mon i_hdmi_clock_mon (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_d_count (up_hdmi_clk_count_s),
.d_rst (hdmi_rst),
.d_clk (hdmi_clk));
// vdma control & status
up_xfer_status #(.DATA_WIDTH(3)) i_vdma_xfer_status (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_data_status ({up_vdma_ovf_s,
up_vdma_unf_s,
up_vdma_tpm_oos_s}),
.d_rst (hdmi_rst),
.d_clk (hdmi_clk),
.d_data_status ({ vdma_ovf,
vdma_unf,
vdma_tpm_oos}));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,124 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_xfer_cntrl (
// up interface
up_rstn,
up_clk,
up_data_cntrl,
// device interface
d_rst,
d_clk,
d_data_cntrl);
// parameters
parameter DATA_WIDTH = 8;
localparam DW = DATA_WIDTH - 1;
// up interface
input up_rstn;
input up_clk;
input [DW:0] up_data_cntrl;
// device interface
input d_rst;
input d_clk;
output [DW:0] d_data_cntrl;
// internal registers
reg [ 5:0] up_xfer_count = 'd0;
reg up_xfer_toggle = 'd0;
reg [DW:0] up_xfer_data = 'd0;
reg d_xfer_toggle_m1 = 'd0;
reg d_xfer_toggle_m2 = 'd0;
reg d_xfer_toggle_m3 = 'd0;
reg [DW:0] d_data_cntrl = 'd0;
// internal signals
wire d_xfer_toggle_s;
// device control transfer
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_xfer_count <= 'd0;
up_xfer_toggle <= 'd0;
up_xfer_data <= 'd0;
end else begin
up_xfer_count <= up_xfer_count + 1'd1;
if (up_xfer_count == 6'd1) begin
up_xfer_toggle <= ~up_xfer_toggle;
up_xfer_data <= up_data_cntrl;
end
end
end
assign d_xfer_toggle_s = d_xfer_toggle_m3 ^ d_xfer_toggle_m2;
always @(posedge d_clk) begin
if (d_rst == 1'b1) begin
d_xfer_toggle_m1 <= 'd0;
d_xfer_toggle_m2 <= 'd0;
d_xfer_toggle_m3 <= 'd0;
d_data_cntrl <= 'd0;;
end else begin
d_xfer_toggle_m1 <= up_xfer_toggle;
d_xfer_toggle_m2 <= d_xfer_toggle_m1;
d_xfer_toggle_m3 <= d_xfer_toggle_m2;
if (d_xfer_toggle_s == 1'b1) begin
d_data_cntrl <= up_xfer_data;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,131 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module up_xfer_status (
// up interface
up_rstn,
up_clk,
up_data_status,
// device interface
d_rst,
d_clk,
d_data_status);
// parameters
parameter DATA_WIDTH = 8;
localparam DW = DATA_WIDTH - 1;
// up interface
input up_rstn;
input up_clk;
output [DW:0] up_data_status;
// device interface
input d_rst;
input d_clk;
input [DW:0] d_data_status;
// internal registers
reg [ 5:0] d_xfer_count = 'd0;
reg d_xfer_toggle = 'd0;
reg [DW:0] d_xfer_data = 'd0;
reg [DW:0] d_acc_data = 'd0;
reg up_xfer_toggle_m1 = 'd0;
reg up_xfer_toggle_m2 = 'd0;
reg up_xfer_toggle_m3 = 'd0;
reg [DW:0] up_data_status = 'd0;
// internal signals
wire up_xfer_toggle_s;
// device status transfer
always @(posedge d_clk) begin
if (d_rst == 1'b1) begin
d_xfer_count <= 'd0;
d_xfer_toggle <= 'd0;
d_xfer_data <= 'd0;
d_acc_data <= 'd0;
end else begin
d_xfer_count <= d_xfer_count + 1'd1;
if (d_xfer_count == 6'd1) begin
d_xfer_toggle <= ~d_xfer_toggle;
d_xfer_data <= d_acc_data;
end
if (d_xfer_count == 6'd1) begin
d_acc_data <= d_data_status;
end else begin
d_acc_data <= d_acc_data | d_data_status;
end
end
end
assign up_xfer_toggle_s = up_xfer_toggle_m3 ^ up_xfer_toggle_m2;
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 1'b0) begin
up_xfer_toggle_m1 <= 'd0;
up_xfer_toggle_m2 <= 'd0;
up_xfer_toggle_m3 <= 'd0;
up_data_status <= 'd0;
end else begin
up_xfer_toggle_m1 <= d_xfer_toggle;
up_xfer_toggle_m2 <= up_xfer_toggle_m1;
up_xfer_toggle_m3 <= up_xfer_toggle_m2;
if (up_xfer_toggle_s == 1'b1) begin
up_data_status <= d_xfer_data;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

124
library/scripts/adi_ip.tcl Normal file
View File

@ -0,0 +1,124 @@
# ip related stuff
proc adi_ip_create {ip_name} {
create_project $ip_name . -force
set proj_dir [get_property directory [current_project]]
set proj_name [get_projects $ip_name]
}
proc adi_ip_files {ip_name ip_files} {
set proj_fileset [get_filesets sources_1]
add_files -norecurse -scan_for_includes -fileset $proj_fileset $ip_files
set_property "top" "$ip_name" $proj_fileset
}
proc adi_ip_properties {ip_name} {
ipx::package_project -root_dir .
ipx::remove_memory_map {s_axi} [ipx::current_core]
ipx::add_memory_map {s_axi} [ipx::current_core]
set_property slave_memory_map_ref {s_axi} [ipx::get_bus_interface s_axi [ipx::current_core]]
ipx::add_address_block {axi_lite} [ipx::get_memory_map s_axi [ipx::current_core]]
set_property range {65536} [ipx::get_address_block axi_lite \
[ipx::get_memory_map s_axi [ipx::current_core]]]
set_property vendor {analog.com} [ipx::current_core]
set_property library {user} [ipx::current_core]
set_property taxonomy {{/AXI_Infrastructure}} [ipx::current_core]
set_property vendor_display_name {Analog Devices} [ipx::current_core]
set_property company_url {www.analog.com} [ipx::current_core]
set_property value {0xFFFFFFFF} [ipx::get_hdl_parameter C_HIGHADDR [ipx::current_core]]
set_property value {0x00000000} [ipx::get_hdl_parameter C_BASEADDR [ipx::current_core]]
set_property supported_families \
{{virtex7} {Production} \
{qvirtex7} {Production} \
{kintex7} {Production} \
{kintex7l} {Production} \
{qkintex7} {Production} \
{qkintex7l} {Production} \
{artix7} {Production} \
{artix7l} {Production} \
{aartix7} {Production} \
{qartix7} {Production} \
{zynq} {Production} \
{qzynq} {Production} \
{azynq} {Production}} \
[ipx::current_core]
}
proc adi_ip_properties_lite {ip_name} {
ipx::package_project -root_dir .
set_property vendor {analog.com} [ipx::current_core]
set_property library {user} [ipx::current_core]
set_property taxonomy {{/AXI_Infrastructure}} [ipx::current_core]
set_property vendor_display_name {Analog Devices} [ipx::current_core]
set_property company_url {www.analog.com} [ipx::current_core]
set_property supported_families \
{{virtex7} {Production} \
{qvirtex7} {Production} \
{kintex7} {Production} \
{kintex7l} {Production} \
{qkintex7} {Production} \
{qkintex7l} {Production} \
{artix7} {Production} \
{artix7l} {Production} \
{aartix7} {Production} \
{qartix7} {Production} \
{zynq} {Production} \
{qzynq} {Production} \
{azynq} {Production}} \
[ipx::current_core]
}
proc adi_set_ports_dependency {port_prefix dependency} {
foreach port [ipx::get_ports [format "%s%s" $port_prefix "*"]] {
set_property ENABLEMENT_DEPENDENCY $dependency $port
}
}
proc adi_set_bus_dependency {bus prefix dependency} {
set_property ENABLEMENT_DEPENDENCY $dependency [ipx::get_bus_interface $bus [ipx::current_core]]
adi_set_ports_dependency $prefix $dependency
}
proc adi_add_port_map {bus phys logic} {
set map [ipx::add_port_map $phys $bus]
set_property "PHYSICAL_NAME" $phys $map
set_property "LOGICAL_NAME" $logic $map
}
proc adi_add_bus {bus_name bus_type mode port_maps} {
set bus [ipx::add_bus_interface $bus_name [ipx::current_core]]
if { $bus_type == "axis" } {
set abst_type "axis_rtl"
} elseif { $bus_type == "aximm" } {
set abst_type "aximm_rtl"
} else {
set abst_type $bus_type
}
set_property "ABSTRACTION_TYPE_LIBRARY" "interface" $bus
set_property "ABSTRACTION_TYPE_NAME" $abst_type $bus
set_property "ABSTRACTION_TYPE_VENDOR" "xilinx.com" $bus
set_property "ABSTRACTION_TYPE_VERSION" "1.0" $bus
set_property "BUS_TYPE_LIBRARY" "interface" $bus
set_property "BUS_TYPE_NAME" $bus_type $bus
set_property "BUS_TYPE_VENDOR" "xilinx.com" $bus
set_property "BUS_TYPE_VERSION" "1.0" $bus
set_property "CLASS" "bus_interface" $bus
set_property "INTERFACE_MODE" $mode $bus
foreach port_map $port_maps {
adi_add_port_map $bus {*}$port_map
}
}

View File

@ -0,0 +1,50 @@
-- ***************************************************************************
-- ***************************************************************************
-- ***************************************************************************
-- ***************************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library unisim;
use unisim.all;
entity util_i2c_mixer is
generic (
C_WIDTH: integer := 2
);
port (
upstream_scl_T : in std_logic;
upstream_scl_I : in std_logic;
upstream_scl_O : out std_logic;
upstream_sda_T : in std_logic;
upstream_sda_I : in std_logic;
upstream_sda_O : out std_logic;
downstream_scl_T : out std_logic;
downstream_scl_I : in std_logic_vector(C_WIDTH - 1 downto 0);
downstream_scl_O : out std_logic_vector(C_WIDTH - 1 downto 0);
downstream_sda_T : out std_logic;
downstream_sda_I : in std_logic_vector(C_WIDTH - 1 downto 0);
downstream_sda_O : out std_logic_vector(C_WIDTH - 1 downto 0)
);
end util_i2c_mixer;
architecture IMP of util_i2c_mixer is
begin
upstream_scl_O <= '1' when (downstream_scl_I = (downstream_scl_I'range => '1')) else '0';
upstream_sda_O <= '1' when (downstream_sda_I = (downstream_sda_I'range => '1')) else '0';
downstream_scl_T <= upstream_scl_T;
downstream_sda_T <= upstream_sda_T;
GEN: for i in 0 to C_WIDTH - 1 generate
downstream_scl_O(i) <= upstream_scl_I;
downstream_sda_O(i) <= upstream_sda_I;
end generate GEN;
end IMP;

View File

@ -0,0 +1,12 @@
# ip
source ../scripts/adi_ip.tcl
adi_ip_create util_i2c_mixer
adi_ip_files util_i2c_mixer [list \
"util_i2c_mixer.vhd" ]
adi_ip_properties_lite util_i2c_mixer
ipx::save_core [ipx::current_core]