1 |
2 |
racerxdl |
//////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Xilinx, Inc. 2006 www.xilinx.com
|
4 |
|
|
//
|
5 |
|
|
// XAPP 486 - 7:1 LVDS in Spartan3E Devices
|
6 |
|
|
//
|
7 |
|
|
//////////////////////////////////////////////////////////////////////////////
|
8 |
|
|
//
|
9 |
|
|
// File name : top4_tx.v
|
10 |
|
|
//
|
11 |
|
|
// Description : Example top level module for using a 4-bit transmitter in Spartan 3E
|
12 |
|
|
//
|
13 |
|
|
// Date - revision : October 16th 2006 - v 1.4
|
14 |
|
|
//
|
15 |
|
|
// Version 1.4 : Brings the DDR registers to the top level and no
|
16 |
|
|
// longer uses 'C0' alignment
|
17 |
|
|
//
|
18 |
|
|
// Author : NJS
|
19 |
|
|
//
|
20 |
|
|
// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
|
21 |
|
|
// provided to you "as is". Xilinx and its licensors make and you
|
22 |
|
|
// receive no warranties or conditions, express, implied,
|
23 |
|
|
// statutory or otherwise, and Xilinx specifically disclaims any
|
24 |
|
|
// implied warranties of merchantability, non-infringement,or
|
25 |
|
|
// fitness for a particular purpose. Xilinx does not warrant that
|
26 |
|
|
// the functions contained in these designs will meet your
|
27 |
|
|
// requirements, or that the operation of these designs will be
|
28 |
|
|
// uninterrupted or error free, or that defects in the Designs
|
29 |
|
|
// will be corrected. Furthermore, Xilinx does not warrantor
|
30 |
|
|
// make any representations regarding use or the results of the
|
31 |
|
|
// use of the designs in terms of correctness, accuracy,
|
32 |
|
|
// reliability, or otherwise.
|
33 |
|
|
//
|
34 |
|
|
// LIMITATION OF LIABILITY. In no event will Xilinx or its
|
35 |
|
|
// licensors be liable for any loss of data, lost profits,cost
|
36 |
|
|
// or procurement of substitute goods or services, or for any
|
37 |
|
|
// special, incidental, consequential, or indirect damages
|
38 |
|
|
// arising from the use or operation of the designs or
|
39 |
|
|
// accompanying documentation, however caused and on any theory
|
40 |
|
|
// of liability. This limitation will apply even if Xilinx
|
41 |
|
|
// has been advised of the possibility of such damage. This
|
42 |
|
|
// limitation shall apply not-withstanding the failure of the
|
43 |
|
|
// essential purpose of any limited remedies herein.
|
44 |
|
|
//
|
45 |
|
|
// Copyright © 2006 Xilinx, Inc.
|
46 |
|
|
// All rights reserved
|
47 |
|
|
//
|
48 |
|
|
//////////////////////////////////////////////////////////////////////////////
|
49 |
|
|
//
|
50 |
|
|
`timescale 1 ps / 1ps
|
51 |
|
|
|
52 |
|
|
module top4_tx(
|
53 |
|
|
input clkint, // clock in
|
54 |
|
|
input [27:0] datain, // 28 bit data in
|
55 |
|
|
input rstin, // reset (active low)
|
56 |
|
|
output [3:0] dataouta_p, dataouta_n, // lvds data outputs
|
57 |
|
|
output clkouta1_p, clkouta1_n) ; // lvds clock output
|
58 |
|
|
|
59 |
|
|
wire low ; // logic 1'b0
|
60 |
|
|
wire high ; // logic 1'b1
|
61 |
|
|
wire rst ; // reset wire
|
62 |
|
|
wire inclk ; //
|
63 |
|
|
wire inclknot ; //
|
64 |
|
|
wire clk ; // main clock from DCM
|
65 |
|
|
wire clknot ; // inverted main clock from DCM
|
66 |
|
|
wire clkdcm ; // clock from dcm
|
67 |
|
|
wire clkx3p5 ; // 3.5x clock for transmitter
|
68 |
|
|
wire clkx3p5dcm ; // 3.5x clock from dcm
|
69 |
|
|
wire clkx3p5notdcm ; // not 3.5x clock from dcm
|
70 |
|
|
wire [7:0] outdata ; // output data lines
|
71 |
|
|
wire clkoutint ; // forwarded output clock
|
72 |
|
|
wire [1:0] oclkinta ; //
|
73 |
|
|
wire clkoutaint ; // forwarded output clock from macro 3:4 or 4:3 duty cycle
|
74 |
|
|
wire clkoutbint ; // forwarded output clock using DCM clk0 - 50% output duty cycle
|
75 |
|
|
wire clkoutcint ; // forwarded output clock just using BUFG - output duty cycle = input duty cycle
|
76 |
|
|
wire clkoutdint ; // output clock being used to monitor CLKFX and CLKFX180
|
77 |
|
|
wire clk_lckd ; // clock locked
|
78 |
|
|
wire not_clk_lckd ; // not clock locked
|
79 |
|
|
reg [27:0] txdata = 0 ; // data for transmission
|
80 |
|
|
wire clkx3p5not ; // inverted 3.5x clock
|
81 |
|
|
wire rst_clk ; // reset syncced to main clock
|
82 |
|
|
wire [7:0] tx_output_fix ;
|
83 |
|
|
wire [3:0] tx_output_reg ;
|
84 |
|
|
|
85 |
|
|
parameter [3:0] TX_SWAP_MASK = 4'b0000 ; // pinswap mask for 4 output bits (0 = no swap (default), 1 = swap)
|
86 |
|
|
|
87 |
|
|
assign low = 1'b0 ;
|
88 |
|
|
assign high = 1'b1 ;
|
89 |
|
|
assign rst = ~rstin ; // reset is active low
|
90 |
|
|
assign clknot = ~clk ;
|
91 |
|
|
assign inclknot = ~inclk ;
|
92 |
|
|
|
93 |
|
|
DCM_SP #(.CLKIN_PERIOD ("15.625"),
|
94 |
|
|
.DESKEW_ADJUST ("0"),
|
95 |
|
|
.CLKFX_MULTIPLY (7),
|
96 |
|
|
.CLKFX_DIVIDE (2))
|
97 |
|
|
dcm_clk (
|
98 |
|
|
.CLKIN (clkint),
|
99 |
|
|
.CLKFB (clk),
|
100 |
|
|
.DSSEN (low),
|
101 |
|
|
.PSINCDEC (low),
|
102 |
|
|
.PSEN (low),
|
103 |
|
|
.PSCLK (low),
|
104 |
|
|
.RST (rst),
|
105 |
|
|
.CLK0 (clkdcm),
|
106 |
|
|
.CLK90 (clkdx),
|
107 |
|
|
.CLKFX (clkx3p5dcm),
|
108 |
|
|
.CLKFX180 (clkx3p5notdcm),
|
109 |
|
|
.LOCKED (clk_lckd),
|
110 |
|
|
.PSDONE (),
|
111 |
|
|
.STATUS ()) ;
|
112 |
|
|
wire clkdxnot;
|
113 |
|
|
assign clkdxnot = ~clkdx ;
|
114 |
|
|
|
115 |
|
|
BUFG inclk_bufg (.I(clkint), .O(inclk) ) ;
|
116 |
|
|
BUFG clk_bufg (.I(clkdcm), .O(clk) ) ;
|
117 |
|
|
BUFG clkx3p5_bufg (.I(clkx3p5dcm), .O(clkx3p5) ) ;
|
118 |
|
|
BUFG clkx3p5not_bufg (.I(clkx3p5notdcm), .O(clkx3p5not) ) ;
|
119 |
|
|
|
120 |
|
|
genvar i ;
|
121 |
|
|
generate
|
122 |
|
|
for (i = 0 ; i <= 3 ; i = i + 1)
|
123 |
|
|
begin : loop0
|
124 |
|
|
OBUFDS #(.IOSTANDARD("LVDS_33"))
|
125 |
|
|
obuf_d (.I(tx_output_reg[i]), .O(dataouta_p[i]), .OB(dataouta_n[i]));
|
126 |
|
|
ODDR2 #(.DDR_ALIGNMENT("NONE")) fd_ioc (.C0(clkx3p5), .C1(clkx3p5not), .D0(tx_output_fix[i+4]), .D1(tx_output_fix[i]), .CE(1'b1), .R(1'b0), .S(1'b0), .Q(tx_output_reg[i])) ;
|
127 |
|
|
assign tx_output_fix[i] = outdata[i] ^ TX_SWAP_MASK[i] ;
|
128 |
|
|
assign tx_output_fix[i+4] = outdata[i+4] ^ TX_SWAP_MASK[i] ;
|
129 |
|
|
end
|
130 |
|
|
endgenerate
|
131 |
|
|
|
132 |
|
|
ODDR2 #(.DDR_ALIGNMENT("NONE")) ca_ddr_reg (.C0(clkx3p5), .C1(clkx3p5not), .D0(oclkinta[1]), .D1(oclkinta[0]), .CE(1'b1), .R(1'b0), .S(1'b0), .Q(clkoutaint)) ;
|
133 |
|
|
|
134 |
|
|
assign clkoutint = clkoutaint ; // use this line for 3:4 or 4:3 macro generated forwarded clock
|
135 |
|
|
|
136 |
|
|
OBUFDS #(.IOSTANDARD("LVDS_33")) lvds_clka_obuf (.I(clkoutint), .O(clkouta1_p), .OB(clkouta1_n) );
|
137 |
|
|
|
138 |
|
|
serdes_4b_7to1_wrapper tx0(
|
139 |
|
|
.clk (clk),
|
140 |
|
|
.datain (txdata),
|
141 |
|
|
.rst (rst_clk),
|
142 |
|
|
.clkx3p5 (clkx3p5),
|
143 |
|
|
.clkx3p5not (clkx3p5not),
|
144 |
|
|
.dataout (outdata),
|
145 |
|
|
.clkout (oclkinta)); // clock output
|
146 |
|
|
|
147 |
|
|
always @ (posedge clk or posedge rst_clk)
|
148 |
|
|
begin
|
149 |
|
|
if (rst_clk == 1'b1) begin
|
150 |
|
|
txdata <= 28'b0000000000000000000000000000 ;
|
151 |
|
|
end
|
152 |
|
|
else begin
|
153 |
|
|
txdata <= datain ;
|
154 |
|
|
end
|
155 |
|
|
end
|
156 |
|
|
|
157 |
|
|
assign not_clk_lckd = ~clk_lckd ;
|
158 |
|
|
|
159 |
|
|
// generate a registered reset wire for the tx clock
|
160 |
|
|
FDP fd_rst_clk (.D(not_clk_lckd), .C(clk), .PRE(rst), .Q(rst_clk)) ;
|
161 |
|
|
|
162 |
|
|
endmodule
|
163 |
|
|
|
164 |
|
|
|