Skip to content

ad485x_fmcz: Add 3 wire SPI support for LVDS #1635

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/projects/ad485x_fmcz/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Supported carriers
| :adi:`EVAL-AD4858` | ZedBoard | FMC LPC |
+--------------------+ | |
| :adi:`EVAL-AD4857` | | |
+--------------------+----------+----------+

Block design
-------------------------------------------------------------------------------

Expand Down Expand Up @@ -157,6 +159,13 @@ To build the LVDS version of the interface, run:
$cd hdl/projects/ad485x_fmc/zed
$make LVDS_CMOS_N=1

The default LVDS configuration is for 4 wire SPI. To use the 3 wire SPI, run:

.. shell:: bash

$cd hdl/projects/ad485x_fmc/zed
$make LVDS_CMOS_N=1 THREE_W_SPI=1

A more comprehensive build guide can be found in the :ref:`build_hdl` user
guide.

Expand Down
1 change: 1 addition & 0 deletions projects/ad485x_fmcz/zed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ M_DEPS += ../../scripts/adi_pd.tcl
M_DEPS += ../../common/zed/zed_system_constr.xdc
M_DEPS += ../../common/zed/zed_system_bd.tcl
M_DEPS += ../../../library/common/ad_iobuf.v
M_DEPS += ../../../library/common/ad_3w_spi.v

LIB_DEPS += axi_ad485x
LIB_DEPS += axi_clkgen
Expand Down
24 changes: 20 additions & 4 deletions projects/ad485x_fmcz/zed/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ if [info exists ::env(LVDS_CMOS_N)] {
set env(LVDS_CMOS_N) $LVDS_CMOS_N
}

set THREE_W_SPI 0
if [info exists ::env(THREE_W_SPI)] {
set THREE_W_SPI $::env(THREE_W_SPI)
} else {
set env(THREE_W_SPI) $THREE_W_SPI
}

set DEVICE "AD4858"
if [info exists ::env(DEVICE)] {
set DEVICE $::env(DEVICE)
Expand All @@ -26,6 +33,7 @@ if [info exists ::env(DEVICE)] {
adi_project ad485x_fmcz_zed 0 [list \
LVDS_CMOS_N $LVDS_CMOS_N \
DEVICE $DEVICE \
THREE_W_SPI $THREE_W_SPI \
]

if {$LVDS_CMOS_N == "0"} {
Expand All @@ -42,15 +50,23 @@ if {$LVDS_CMOS_N == "0"} {
]
}
} else {
adi_project_files {} [list \
"system_top_lvds.v" \
"system_constr_lvds.xdc" \
]
if {$THREE_W_SPI == "0"} {
adi_project_files {} [list \
"system_top_lvds.v" \
"system_constr_lvds.xdc" \
]
} else {
adi_project_files {} [list \
"system_top_lvds_3w_spi.v" \
"system_constr_lvds.xdc" \
]
}
}

adi_project_files {} [list \
"$ad_hdl_dir/projects/common/zed/zed_system_constr.xdc" \
"$ad_hdl_dir/library/common/ad_iobuf.v" \
"$ad_hdl_dir/library/common/ad_3w_spi.v" \
]

adi_project_run ad485x_fmcz_zed
247 changes: 247 additions & 0 deletions projects/ad485x_fmcz/zed/system_top_lvds_3w_spi.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2025 Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************

`timescale 1ns/100ps

module system_top (
inout [14:0] ddr_addr,
inout [ 2:0] ddr_ba,
inout ddr_cas_n,
inout ddr_ck_n,
inout ddr_ck_p,
inout ddr_cke,
inout ddr_cs_n,
inout [ 3:0] ddr_dm,
inout [31:0] ddr_dq,
inout [ 3:0] ddr_dqs_n,
inout [ 3:0] ddr_dqs_p,
inout ddr_odt,
inout ddr_ras_n,
inout ddr_reset_n,
inout ddr_we_n,

inout fixed_io_ddr_vrn,
inout fixed_io_ddr_vrp,
inout [53:0] fixed_io_mio,
inout fixed_io_ps_clk,
inout fixed_io_ps_porb,
inout fixed_io_ps_srstb,

inout [31:0] gpio_bd,

output hdmi_out_clk,
output hdmi_vsync,
output hdmi_hsync,
output hdmi_data_e,
output [15:0] hdmi_data,

output i2s_mclk,
output i2s_bclk,
output i2s_lrclk,
output i2s_sdata_out,
input i2s_sdata_in,

output spdif,

inout iic_scl,
inout iic_sda,
inout [ 1:0] iic_mux_scl,
inout [ 1:0] iic_mux_sda,

input otg_vbusoc,

output scki_p,
output scki_n,
input scko_p,
input scko_n,
input sdo_p,
input sdo_n,

input busy,
output cnv,
output pd,
output lvds_cmos_n,

output reg csck, //spiad_sck
inout csdio,//spiad_sdi
output reg cs_n //spiad_csn
);

// internal signals

wire [63:0] gpio_i;
wire [63:0] gpio_o;
wire [63:0] gpio_t;
wire [ 1:0] iic_mux_scl_i_s;
wire [ 1:0] iic_mux_scl_o_s;
wire iic_mux_scl_t_s;
wire [ 1:0] iic_mux_sda_i_s;
wire [ 1:0] iic_mux_sda_o_s;
wire iic_mux_sda_t_s;

assign gpio_i[63:32] = gpio_o[63:32];
assign pd = gpio_o[32];

wire spiad_sck_s;
wire spiad_csn_s;
wire miso_s;
wire mosi_s;
reg [ 4:0] cnt_cs_up = 3'd0;

always @(posedge cpu_clk) begin
csck <= spiad_sck_s;
if (spiad_csn_s == 1'b0) begin
cs_n <= 1'b0;
cnt_cs_up <= 3'd0;
end else if (cnt_cs_up == 5'h1f) begin
cs_n <= 1'b0;
cnt_cs_up <= cnt_cs_up;
end else begin
cs_n <= 1'b1;
cnt_cs_up <= cnt_cs_up + 3'd1;
end
end

// instantiations

ad_3w_spi #(
.NUM_OF_SLAVES(2)
) i_spi (
.spi_csn(spiad_csn_s),
.spi_clk(spiad_sck_s),
.spi_mosi(mosi_s),
.spi_miso(miso_s),
.spi_sdio(csdio),
.spi_dir());

ad_iobuf #(
.DATA_WIDTH(32)
) i_iobuf (
.dio_t(gpio_t[31:0]),
.dio_i(gpio_o[31:0]),
.dio_o(gpio_i[31:0]),
.dio_p(gpio_bd));

ad_iobuf #(
.DATA_WIDTH(2)
) i_iic_mux_scl (
.dio_t({iic_mux_scl_t_s, iic_mux_scl_t_s}),
.dio_i(iic_mux_scl_o_s),
.dio_o(iic_mux_scl_i_s),
.dio_p(iic_mux_scl));

ad_iobuf #(
.DATA_WIDTH(2)
) i_iic_mux_sda (
.dio_t({iic_mux_sda_t_s, iic_mux_sda_t_s}),
.dio_i(iic_mux_sda_o_s),
.dio_o(iic_mux_sda_i_s),
.dio_p(iic_mux_sda));

system_wrapper i_system_wrapper (
.ddr_addr (ddr_addr),
.ddr_ba (ddr_ba),
.ddr_cas_n (ddr_cas_n),
.ddr_ck_n (ddr_ck_n),
.ddr_ck_p (ddr_ck_p),
.ddr_cke (ddr_cke),
.ddr_cs_n (ddr_cs_n),
.ddr_dm (ddr_dm),
.ddr_dq (ddr_dq),
.ddr_dqs_n (ddr_dqs_n),
.ddr_dqs_p (ddr_dqs_p),
.ddr_odt (ddr_odt),
.ddr_ras_n (ddr_ras_n),
.ddr_reset_n (ddr_reset_n),
.ddr_we_n (ddr_we_n),
.fixed_io_ddr_vrn (fixed_io_ddr_vrn),
.fixed_io_ddr_vrp (fixed_io_ddr_vrp),
.fixed_io_mio (fixed_io_mio),
.fixed_io_ps_clk (fixed_io_ps_clk),
.fixed_io_ps_porb (fixed_io_ps_porb),
.fixed_io_ps_srstb (fixed_io_ps_srstb),
.gpio_i (gpio_i),
.gpio_o (gpio_o),
.gpio_t (gpio_t),
.hdmi_data (hdmi_data),
.hdmi_data_e (hdmi_data_e),
.hdmi_hsync (hdmi_hsync),
.hdmi_out_clk (hdmi_out_clk),
.hdmi_vsync (hdmi_vsync),
.i2s_bclk (i2s_bclk),
.i2s_lrclk (i2s_lrclk),
.i2s_mclk (i2s_mclk),
.i2s_sdata_in (i2s_sdata_in),
.i2s_sdata_out (i2s_sdata_out),
.iic_fmc_scl_io (iic_scl),
.iic_fmc_sda_io (iic_sda),
.iic_mux_scl_i (iic_mux_scl_i_s),
.iic_mux_scl_o (iic_mux_scl_o_s),
.iic_mux_scl_t (iic_mux_scl_t_s),
.iic_mux_sda_i (iic_mux_sda_i_s),
.iic_mux_sda_o (iic_mux_sda_o_s),
.iic_mux_sda_t (iic_mux_sda_t_s),
.otg_vbusoc (otg_vbusoc),
.spdif (spdif),
.system_cpu_clk (cpu_clk),
.spi0_clk_i (spiad_sck_s),
.spi0_clk_o (spiad_sck_s),
.spi0_csn_0_o (spiad_csn_s),
.spi0_csn_1_o (),
.spi0_csn_2_o (),
.spi0_csn_i (1'b1),
.spi0_sdi_i (miso_s),
.spi0_sdo_i (mosi_s),
.spi0_sdo_o (mosi_s),
.spi1_clk_i (1'b0),
.spi1_clk_o (),
.spi1_csn_0_o (),
.spi1_csn_1_o (),
.spi1_csn_2_o (),
.spi1_csn_i (1'b1),
.spi1_sdi_i (1'b0),
.spi1_sdo_i (1'b0),
.spi1_sdo_o (),
.scki_p (scki_p),
.scki_n (scki_n),
.scko_p (scko_p),
.scko_n (scko_n),
.sdo_p (sdo_p),
.sdo_n (sdo_n),
.busy (busy),
.cnv (cnv),
.lvds_cmos_n (lvds_cmos_n));

endmodule