aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2020-01-23 16:10:22 -0800
committerMartin Braun <martin.braun@ettus.com>2020-01-28 09:35:36 -0800
commitbafa9d95453387814ef25e6b6256ba8db2df612f (patch)
tree39ba24b5b67072d354775272e687796bb511848d /fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v
parent3075b981503002df3115d5f1d0b97d2619ba30f2 (diff)
downloaduhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.gz
uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.bz2
uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.zip
Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce the size of the repository. However, over the last half-decade, the split between the repositories has proven more burdensome than it has been helpful. By merging the FPGA code back, it will be possible to create atomic commits that touch both FPGA and UHD codebases. Continuous integration testing is also simplified by merging the repositories, because it was previously difficult to automatically derive the correct UHD branch when testing a feature branch on the FPGA repository. This commit also updates the license files and paths therein. We are therefore merging the repositories again. Future development for FPGA code will happen in the same repository as the UHD host code and MPM code. == Original Codebase and Rebasing == The original FPGA repository will be hosted for the foreseeable future at its original local location: https://github.com/EttusResearch/fpga/ It can be used for bisecting, reference, and a more detailed history. The final commit from said repository to be merged here is 05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as v4.0.0.0-pre-uhd-merge. If you have changes in the FPGA repository that you want to rebase onto the UHD repository, simply run the following commands: - Create a directory to store patches (this should be an empty directory): mkdir ~/patches - Now make sure that your FPGA codebase is based on the same state as the code that was merged: cd src/fpga # Or wherever your FPGA code is stored git rebase v4.0.0.0-pre-uhd-merge Note: The rebase command may look slightly different depending on what exactly you're trying to rebase. - Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge: git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches Note: Make sure that only patches are stored in your output directory. It should otherwise be empty. Make sure that you picked the correct range of commits, and only commits you wanted to rebase were exported as patch files. - Go to the UHD repository and apply the patches: cd src/uhd # Or wherever your UHD repository is stored git am --directory fpga ~/patches/* rm -rf ~/patches # This is for cleanup == Contributors == The following people have contributed mainly to these files (this list is not complete): Co-authored-by: Alex Williams <alex.williams@ni.com> Co-authored-by: Andrej Rode <andrej.rode@ettus.com> Co-authored-by: Ashish Chaudhari <ashish@ettus.com> Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com> Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Derek Kozel <derek.kozel@ettus.com> Co-authored-by: EJ Kreinar <ej@he360.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Ian Buckley <ian.buckley@gmail.com> Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Jon Kiser <jon.kiser@ni.com> Co-authored-by: Josh Blum <josh@joshknows.com> Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Matt Ettus <matt@ettus.com> Co-authored-by: Michael West <michael.west@ettus.com> Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com> Co-authored-by: Nick Foster <nick@ettus.com> Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Paul David <paul.david@ettus.com> Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com> Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com> Co-authored-by: Sylvain Munaut <tnt@246tNt.com> Co-authored-by: Trung Tran <trung.tran@ettus.com> Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com> Co-authored-by: Wade Fife <wade.fife@ettus.com>
Diffstat (limited to 'fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v')
-rw-r--r--fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v396
1 files changed, 396 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v b/fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v
new file mode 100644
index 000000000..2c412d7f3
--- /dev/null
+++ b/fpga/usrp3/lib/io_cap_gen/cat_output_lvds.v
@@ -0,0 +1,396 @@
+//
+// Copyright 2016 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: cat_output_lvds
+// Description: Transmit interface to AD9361 in LVDS mode.
+//
+// The frame_sample signal controls the expected frame signal timing. When
+// frame_sample is 0, the period of the ddr_frame signal will be equal to two
+// samples (e.g., one from each channel). When frame_sample is 1, the frame
+// period will be equal to the length of one sample. This allows the module to
+// be used for 2R2T (frame_sample = 1) or 1R1T mode (frame_sample = 0).
+
+
+module cat_output_lvds #(
+ parameter INVERT_FRAME_TX = 0,
+ parameter INVERT_DATA_TX = 6'b00_0000,
+ parameter USE_CLOCK_DELAY = 1,
+ parameter USE_DATA_DELAY = 1,
+ parameter CLOCK_DELAY_MODE = "VAR_LOAD",
+ parameter DATA_DELAY_MODE = "VAR_LOAD",
+ parameter CLOCK_DELAY = 0,
+ parameter DATA_DELAY = 0,
+ parameter WIDTH = 6,
+ parameter GROUP = "DEFAULT"
+) (
+ input clk200,
+ input rst,
+
+ // Data and frame timing (synchronous to radio_clk)
+ input frame_sample, // Two samples per frame period (frame_sample=0) or one sample per frame (frame_sample=1)
+
+ // Region local Clocks for I/O cells.
+ input ddr_clk,
+ input sdr_clk,
+
+ // Source synchronous external input clock
+ output ddr_clk_p,
+ output ddr_clk_n,
+
+ // Source synchronous data lines
+ output [WIDTH-1:0] ddr_data_p,
+ output [WIDTH-1:0] ddr_data_n,
+ output ddr_frame_p,
+ output ddr_frame_n,
+
+ // Delay control interface
+ input ctrl_clk,
+ input [4:0] ctrl_data_delay,
+ input [4:0] ctrl_clk_delay,
+ input ctrl_ld_data_delay,
+ input ctrl_ld_clk_delay,
+
+ // Global input clock
+ input radio_clk,
+
+ // SDR data buses
+ input [(WIDTH*2)-1:0] i0,
+ input [(WIDTH*2)-1:0] q0,
+ input [(WIDTH*2)-1:0] i1,
+ input [(WIDTH*2)-1:0] q1
+
+);
+
+
+ //------------------------------------------------------------------
+ // UG471 says take reset high asynchronously, and de-assert
+ // synchronized to CLKDIV (sdr_clk) for SERDES.
+ //------------------------------------------------------------------
+ reg rst_sdr_sync;
+
+ always @(posedge sdr_clk or posedge rst)
+ if (rst)
+ rst_sdr_sync <= 1'b1;
+ else
+ rst_sdr_sync <= 1'b0;
+
+ //------------------------------------------------------------------
+ // Route radio data to SERDES for SISO and MIMO modes.
+ //------------------------------------------------------------------
+ reg [(WIDTH*2)-1:0] radio_data_i0, radio_data_q0;
+ reg [(WIDTH*2)-1:0] radio_data_i1, radio_data_q1;
+ reg [(WIDTH*2)-1:0] data_i0, data_q0, data_i1, data_q1;
+ //
+ //
+ always @(posedge radio_clk)
+ begin
+ // When in 2R2T mode, data mapping is the same for SISO and MIMO. The data
+ // for channel 1 will be ignored.
+ radio_data_i0 <= i0;
+ radio_data_q0 <= q0;
+ radio_data_i1 <= i1;
+ radio_data_q1 <= q1;
+ end
+
+ //
+ // Cross data into sdr_clock domain.
+ // sdr_clock leads radio_clk in phase by insertion delay of BUFG.
+ // We can transfer data in this direction with no special logic.
+ // Path length must be radio_clk period - BUFG delay to make timing.
+ //
+ always @(posedge sdr_clk)
+ begin
+ data_i0 <= radio_data_i0 ^ {INVERT_DATA_TX,INVERT_DATA_TX};
+ data_q0 <= radio_data_q0 ^ {INVERT_DATA_TX,INVERT_DATA_TX};
+ data_i1 <= radio_data_i1 ^ {INVERT_DATA_TX,INVERT_DATA_TX};
+ data_q1 <= radio_data_q1 ^ {INVERT_DATA_TX,INVERT_DATA_TX};
+ end
+
+ //------------------------------------------------------------------
+ // Clock output
+ //------------------------------------------------------------------
+ wire ddr_clk_out, ddr_clk_dly;
+
+ OSERDESE2 #(
+ .DATA_RATE_OQ ("DDR"), // DDR, SDR
+ .DATA_RATE_TQ ("DDR"), // DDR, BUF, SDR
+ .DATA_WIDTH (8), // Parallel data width (2-8,10,14)
+ .INIT_OQ (1'b0), // Initial value of OQ output (1'b0,1'b1)
+ .INIT_TQ (1'b0), // Initial value of TQ output (1'b0,1'b1)
+ .SERDES_MODE ("MASTER"), // MASTER, SLAVE
+ .SRVAL_OQ (1'b0), // OQ output value when SR is used (1'b0,1'b1)
+ .SRVAL_TQ (1'b0), // TQ output value when SR is used (1'b0,1'b1)
+ .TBYTE_CTL ("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
+ .TBYTE_SRC ("FALSE"), // Tristate byte source (FALSE, TRUE)
+ .TRISTATE_WIDTH (1) // 3-state converter width (1,4)
+ ) ddr_clk_oserdese2 (
+ .OFB (), // High-speed data output to ODELAYE2
+ .OQ (ddr_clk_out), // High-speed data output direct to OBUF
+ // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
+ .SHIFTOUT1 (),
+ .SHIFTOUT2 (),
+ .TBYTEOUT (),
+ .TFB (),
+ .TQ (),
+ .CLK (ddr_clk),
+ .CLKDIV (sdr_clk),
+ // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
+ .D1 (1'b1), // Canned Clock waveform synthesized as data.
+ .D2 (1'b0),
+ .D3 (1'b1),
+ .D4 (1'b0),
+ .D5 (1'b1),
+ .D6 (1'b0),
+ .D7 (1'b1),
+ .D8 (1'b0),
+ .OCE (1'b1), // Active high clock enable
+ .RST (rst_sdr_sync),
+ // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
+ .SHIFTIN1 (1'b0),
+ .SHIFTIN2 (1'b0),
+ // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
+ .T1 (1'b0),
+ .T2 (1'b0),
+ .T3 (1'b0),
+ .T4 (1'b0),
+ .TBYTEIN (1'b0),
+ .TCE (1'b0)
+ );
+
+ generate
+ if (USE_CLOCK_DELAY) begin : gen_clock_odelay
+ (* IODELAY_GROUP = GROUP *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
+ ODELAYE2 #(
+ .CINVCTRL_SEL ("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
+ .DELAY_SRC ("ODATAIN"), // Delay input (ODATAIN, CLKIN)
+ .HIGH_PERFORMANCE_MODE ("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
+ .ODELAY_TYPE (CLOCK_DELAY_MODE), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
+ .ODELAY_VALUE (CLOCK_DELAY), // Output delay tap setting (0-31)
+ .PIPE_SEL ("FALSE"), // Select pipelined mode, FALSE, TRUE
+ .REFCLK_FREQUENCY (200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
+ .SIGNAL_PATTERN ("CLOCK") // DATA, CLOCK input signal
+ ) ddr_clk_odelaye2 (
+ .CNTVALUEOUT (), // 5-bit output: Counter value output
+ .DATAOUT (ddr_clk_dly), // 1-bit output: Delayed data/clock output
+ .C (ctrl_clk), // 1-bit input: Clock input
+ .CE (1'b0), // 1-bit input: Active high enable increment/decrement input
+ .CINVCTRL (1'b0), // 1-bit input: Dynamic clock inversion input
+ .CLKIN (1'b0), // 1-bit input: Clock delay input
+ .CNTVALUEIN (ctrl_clk_delay), // 5-bit input: Counter value input
+ .INC (1'b0), // 1-bit input: Increment / Decrement tap delay input
+ .LD (ctrl_ld_clk_delay), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
+ // VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
+ .LDPIPEEN (1'b0), // 1-bit input: Enables the pipeline register to load data
+ .ODATAIN (ddr_clk_out), // 1-bit input: Output delay data input
+ .REGRST (1'b0) // 1-bit input: Active-high reset tap-delay input
+ );
+ end else begin
+ assign ddr_clk_dly = ddr_clk_out;
+ end
+ endgenerate
+
+
+
+ OBUFDS ddr_clk_obuf (
+ .O (ddr_clk_p), // Diff_p output (connect directly to top-level port)
+ .OB (ddr_clk_n), // Diff_n output (connect directly to top-level port)
+ .I (ddr_clk_dly) // Buffer input
+ );
+
+
+
+ //------------------------------------------------------------------
+ // Frame Signal
+ //------------------------------------------------------------------
+ wire ddr_frame, ddr_frame_dly;
+
+ OSERDESE2 #(
+ .DATA_RATE_OQ ("DDR"), // DDR, SDR
+ .DATA_RATE_TQ ("DDR"), // DDR, BUF, SDR
+ .DATA_WIDTH (8), // Parallel data width (2-8,10,14)
+ .INIT_OQ (1'b0), // Initial value of OQ output (1'b0,1'b1)
+ .INIT_TQ (1'b0), // Initial value of TQ output (1'b0,1'b1)
+ .SERDES_MODE ("MASTER"), // MASTER, SLAVE
+ .SRVAL_OQ (1'b0), // OQ output value when SR is used (1'b0,1'b1)
+ .SRVAL_TQ (1'b0), // TQ output value when SR is used (1'b0,1'b1)
+ .TBYTE_CTL ("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
+ .TBYTE_SRC ("FALSE"), // Tristate byte source (FALSE, TRUE)
+ .TRISTATE_WIDTH (1) // 3-state converter width (1,4)
+ ) ddr_frame_oserdese2 (
+ .OFB (), // High-speed data output to ODELAYE2
+ .OQ (ddr_frame), // High-speed data output direct to OBUF
+ // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
+ .SHIFTOUT1 (),
+ .SHIFTOUT2 (),
+ .TBYTEOUT (),
+ .TFB (),
+ .TQ (),
+ .CLK (ddr_clk),
+ .CLKDIV (sdr_clk),
+ // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each). Frame is
+ // either 11110000 or 11001100 depending on if frame_sample is true or
+ // false, respectively, and it can be inverted by INVERT_FRAME_TX, becoming
+ // 00001111 or 00110011.
+ .D1 (~INVERT_FRAME_TX[0]),
+ .D2 (~INVERT_FRAME_TX[0]),
+ .D3 (INVERT_FRAME_TX[0] ~^ frame_sample),
+ .D4 (INVERT_FRAME_TX[0] ~^ frame_sample),
+ .D5 (INVERT_FRAME_TX[0] ^ frame_sample),
+ .D6 (INVERT_FRAME_TX[0] ^ frame_sample),
+ .D7 (INVERT_FRAME_TX[0]),
+ .D8 (INVERT_FRAME_TX[0]),
+ .OCE (1'b1), // Active high clock enable
+ .RST (rst_sdr_sync),
+ // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
+ .SHIFTIN1 (1'b0),
+ .SHIFTIN2 (1'b0),
+ // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
+ .T1 (1'b0),
+ .T2 (1'b0),
+ .T3 (1'b0),
+ .T4 (1'b0),
+ .TBYTEIN (1'b0),
+ .TCE (1'b0)
+ );
+
+ generate
+ if (USE_DATA_DELAY) begin : gen_frame_odelay
+ (* IODELAY_GROUP = GROUP *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
+ ODELAYE2 #(
+ .CINVCTRL_SEL ("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
+ .DELAY_SRC ("ODATAIN"), // Delay input (ODATAIN, CLKIN)
+ .HIGH_PERFORMANCE_MODE ("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
+ .ODELAY_TYPE (DATA_DELAY_MODE), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
+ .ODELAY_VALUE (DATA_DELAY), // Output delay tap setting (0-31)
+ .PIPE_SEL ("FALSE"), // Select pipelined mode, FALSE, TRUE
+ .REFCLK_FREQUENCY (200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
+ .SIGNAL_PATTERN ("DATA") // DATA, CLOCK input signal
+ ) ddr_frame_odelaye2 (
+ .CNTVALUEOUT (), // 5-bit output: Counter value output
+ .DATAOUT (ddr_frame_dly), // 1-bit output: Delayed data/clock output
+ .C (ctrl_clk), // 1-bit input: Clock input
+ .CE (1'b0), // 1-bit input: Active high enable increment/decrement input
+ .CINVCTRL (1'b0), // 1-bit input: Dynamic clock inversion input
+ .CLKIN (1'b0), // 1-bit input: Clock delay input
+ .CNTVALUEIN (ctrl_data_delay), // 5-bit input: Counter value input
+ .INC (1'b0), // 1-bit input: Increment / Decrement tap delay input
+ .LD (ctrl_ld_data_delay), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
+ // VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
+ .LDPIPEEN (1'b0), // 1-bit input: Enables the pipeline register to load data
+ .ODATAIN (ddr_frame), // 1-bit input: Output delay data input
+ .REGRST (1'b0) // 1-bit input: Active-high reset tap-delay input
+ );
+ end else begin
+ assign ddr_frame_dly = ddr_frame;
+ end
+ endgenerate
+
+ OBUFDS ddr_frame_obuf (
+ .O (ddr_frame_p), // Diff_p output (connect directly to top-level port)
+ .OB (ddr_frame_n), // Diff_n output (connect directly to top-level port)
+ .I (ddr_frame_dly) // Buffer input
+ );
+
+
+ //------------------------------------------------------------------
+ // Data Bus
+ //------------------------------------------------------------------
+ wire [WIDTH-1:0] ddr_data;
+ wire [WIDTH-1:0] ddr_data_dly ;
+
+
+ // wire [(WIDTH*2)-1:0] sdr_data_i;
+ // wire [(WIDTH*2)-1:0] sdr_data_q;
+
+ genvar i;
+ generate
+ for (i=0 ; i<WIDTH ; i=i+1) begin : generate_data_bus
+
+ OSERDESE2 #(
+ .DATA_RATE_OQ ("DDR"), // DDR, SDR
+ .DATA_RATE_TQ ("DDR"), // DDR, BUF, SDR
+ .DATA_WIDTH (8), // Parallel data width (2-8,10,14)
+ .INIT_OQ (1'b0), // Initial value of OQ output (1'b0,1'b1)
+ .INIT_TQ (1'b0), // Initial value of TQ output (1'b0,1'b1)
+ .SERDES_MODE ("MASTER"), // MASTER, SLAVE
+ .SRVAL_OQ (1'b0), // OQ output value when SR is used (1'b0,1'b1)
+ .SRVAL_TQ (1'b0), // TQ output value when SR is used (1'b0,1'b1)
+ .TBYTE_CTL ("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
+ .TBYTE_SRC ("FALSE"), // Tristate byte source (FALSE, TRUE)
+ .TRISTATE_WIDTH (1) // 3-state converter width (1,4)
+ ) ddr_data_oserdese2 (
+ .OFB (), // High-speed data output to ODELAYE2
+ .OQ (ddr_data[i]), // High-speed data output direct to OBUF
+ // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
+ .SHIFTOUT1 (),
+ .SHIFTOUT2 (),
+ .TBYTEOUT (),
+ .TFB (),
+ .TQ (),
+ .CLK (ddr_clk),
+ .CLKDIV (sdr_clk),
+ // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
+ .D1 (data_i0[WIDTH+i]),
+ .D2 (data_q0[WIDTH+i]),
+ .D3 (data_i0[i]),
+ .D4 (data_q0[i]),
+ .D5 (data_i1[WIDTH+i]),
+ .D6 (data_q1[WIDTH+i]),
+ .D7 (data_i1[i]),
+ .D8 (data_q1[i]),
+ .OCE (1'b1), // Active high clock enable
+ .RST (rst_sdr_sync),
+ // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
+ .SHIFTIN1 (1'b0),
+ .SHIFTIN2 (1'b0),
+ // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
+ .T1 (1'b0),
+ .T2 (1'b0),
+ .T3 (1'b0),
+ .T4 (1'b0),
+ .TBYTEIN (1'b0),
+ .TCE (1'b0)
+ );
+
+ if (USE_DATA_DELAY) begin : gen_data_odelay
+ (* IODELAY_GROUP = GROUP *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
+ ODELAYE2 #(
+ .CINVCTRL_SEL ("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
+ .DELAY_SRC ("ODATAIN"), // Delay input (ODATAIN, CLKIN)
+ .HIGH_PERFORMANCE_MODE ("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
+ .ODELAY_TYPE (DATA_DELAY_MODE), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
+ .ODELAY_VALUE (DATA_DELAY), // Output delay tap setting (0-31)
+ .PIPE_SEL ("FALSE"), // Select pipelined mode, FALSE, TRUE
+ .REFCLK_FREQUENCY (200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
+ .SIGNAL_PATTERN ("DATA") // DATA, CLOCK input signal
+ ) ddr_data_odelaye2 (
+ .CNTVALUEOUT (), // 5-bit output: Counter value output
+ .DATAOUT (ddr_data_dly[i]), // 1-bit output: Delayed data/clock output
+ .C (ctrl_clk), // 1-bit input: Clock input
+ .CE (1'b0), // 1-bit input: Active high enable increment/decrement input
+ .CINVCTRL (1'b0), // 1-bit input: Dynamic clock inversion input
+ .CLKIN (1'b0), // 1-bit input: Clock delay input
+ .CNTVALUEIN (ctrl_data_delay), // 5-bit input: Counter value input
+ .INC (1'b0), // 1-bit input: Increment / Decrement tap delay input
+ .LD (ctrl_ld_data_delay), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
+ // VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
+ .LDPIPEEN (1'b0), // 1-bit input: Enables the pipeline register to load data
+ .ODATAIN (ddr_data[i]), // 1-bit input: Output delay data input
+ .REGRST (1'b0) // 1-bit input: Active-high reset tap-delay input
+ );
+ end else begin
+ assign ddr_data_dly[i] = ddr_data[i];
+ end
+
+ OBUFDS ddr_data_obuf (
+ .O (ddr_data_p[i]), // Diff_p output (connect directly to top-level port)
+ .OB (ddr_data_n[i]), // Diff_n output (connect directly to top-level port)
+ .I (ddr_data_dly[i]) // Buffer input
+ );
+ end // block: generate_data_bus
+
+ endgenerate
+
+endmodule // cat_output_lvds